2015-04-11 2 views
4

Я знаю, этот вопрос был обработан т раз .. но я не могу заставить его работать в любом случае .. здесь я вставляю код:Использование CIN для ввода с клавиатуры после обработки перенаправлены ввода файла с GetLine

#include <sstream> 
#include "header.h" 
using namespace std; 
using namespace header; 

int main(){ 
    string parent, child, line, node; 
    int choose = 0; 
    tree_ptr tree_inst = new tree; 
    cout << "*** Start ***" << endl;  
    while (getline(cin, line, '\n')){ 
     istringstream line_stream(line); 
     line_stream >> parent; 
     if (parent.compare("0") == 0) break; 
     while (line_stream >> child) { 
      if (!tree_inst->insert(parent, child)) { 
       cout << "*** ERROR! ***" << endl; 
       tree_inst->visit(tree_inst->root); 
       cout << "*** End ***" << endl; 
       return -1; 
      } 
     } 
    } 
    while (true) { 
     cin >> choose; //<== doesn't wait for the input, just loop forever 
         // on the default statement of the switch... 
     switch (choose) { 
      ... 
     } 
    } 
} 

Я уже пытался вставить некоторые cin.sync() cin.clear() cin.ignore() ..etc .. но ничего не изменилось!

+0

PS: «строка» и «iostream» включены в «header.h». . – Moriduri

+2

Каков ваш ввод, если это не что-то, что может быть проанализировано как целое число, текст не будет удален из входного буфера, так что следующий цикл будет снова прочитан один и тот же ввод. Вам нужно * оба * игнорировать остальную часть строки * и * очистить ошибку. См. Пример в этой ['std :: istream :: ignore'] (http://en.cppreference.com/w/cpp/io/basic_istream/ignore) ссылке, как это сделать. –

+0

Хорошо, я попробую! в любом случае входной файл представляет собой текстовый файл (в Linux я использую консоль для потоковой передачи файла в программу с помощью «./myprogram <текст»), вот пример ввода: parent child1 child 2 \ n parent1 child1 child2 child 3 \ n ... – Moriduri

ответ

1

Первый цикл getline() будет зацикливаться навсегда, если вы его не сломаете так или иначе. Если это сделано чистым способом, это не должно быть проблемой вообще. На самом деле я не смог воспроизвести вашу ошибку.

Как анализировать ошибки

Таким образом, причиной является либо плохо насытить из cin или отсутствия Numberic, не пространства ввода, который до сих пор в ожидании. Чтобы помочь вам узнать, я предлагаю вам добавить диагностический код:

cout << "Enter free lines of text or stop to return to the menu:"; 
while (getline(cin, line, '\n')) { // This would loop foreved 
    if (line == "stop")    // I added this one to exit 
     break;      // but how do you do ? 
} 
while (true) {      // I get no problem here 
    cout << "Cin status: failed=" // <===Add this simple diagnostic to 
     << cin.fail() << " bad=" //  check the state of the stream 
     << cin.bad() << " eof=" << cin.eof() << endl; 
    cout << "Next char in decimal is:" // <=== Add this to show 
     << cin.peek() << endl;  //  where in the stream you're hanging 
    cout << "Choose:"; 
    cin >> choose; 
    cout << "selected: " << choose << endl; 
} 

Если состояние потока не является чистым, несмотря на cin.clean(), это потому, что либо вы закрыли поток или набраны в коде конца-файла на консоли (Ctrl + D или Ctrl + Z в зависимости от системы).

Это состояние потока чистое, но символ peeked не является числовым (то есть десятичным кодом не от 48 до 57), это плохой ввод, который устанавливает поток в состояние сбоя.

Edit: ваш конкретный случай

Глядя на диагностических вы предоставили (невыполнению = 1, ВФ = 1), то оказывается, что после первого цикла вы уже eached конца ввода. Таким образом, ваш вход завершается сбоем, потому что нет никаких данных для чтения. Ваш входной файл на pastebin подтверждает, что последняя строка - это «0», которую вы используете для выхода из первого цикла.

После наших обменов я понимаю, что вы действительно перенаправили ввод из командной строки (например, yourprogramme <yourinput.txt) и ожидаете, что ваш код переключится на ввод с клавиатуры, как только перенаправленный вход файла достигнет своего конца. К сожалению, это не так, как это работает. Если вы перенаправляете ввод из файла, cin всегда будет ссылаться на переназначенный файл.

Чтобы иметь возможность смешивать файл и клавиатуры, вам нужно использовать <fstream> и более точно ifstream для чтения из файла и сохранить cin для ввода с клавиатуры.

Вот немного измененный код, который принимает имя файла из командной строки, но без косвенностью (например yourprogramme yourinput.txt):

... 
int main(int argc, char**argv) 
{ 
    if (argc != 2) {  // if called from command line wrong arguments 
     cerr << "You must provide the name of the data file as command line argument\n"; 
     return EXIT_FAILURE; 
    } 
    ifstream file(argv[1]);  // open the file for reading 
    if (!file) {    // if open failed, end the programme 
     cerr << "Could not open "<<argv[1]<<"\n"; 
     return EXIT_FAILURE; 
    } 
    string line;    // here your code from before 
    int choose = 0; 
    cout << "*** Loading "<<argv[1]<< " ***" << endl; 
           // but in the first loop replace cin with file 
    while (getline(file, line, '\n')){ 
     cout << "Read: " << line<<endl; 
     if (line == "0")    // Abridged version;-) 
      break; 
    } 
    file.close();    // File is no longer needed here. 
    while (true) {    // Second loop, unchanged, using cin 
     cout << "Choose (9 to exit):"; 
     if (!(cin >> choose)) // avoid looping forever if problem on cin 
      break; 
     cout << "selected: " << choose << endl; 
     if (choose == 9) 
      break; 
    } 
return EXIT_SUCCESS; 
} 
+0

Выход теперь (с cout и cin.fail cin.bad ...): Состояние Cin: failed = 1 bad = 0 eof = 1 Следующий символ в десятичной форме: -1 – Moriduri

+0

@Moriduri это означает, что вы наверняка достигли конца файла. (eof == 1 и заглянуть в -1). Удалили ли вы cin.ignore() предыдущих тестов? – Christophe

+0

да! Я удалил его – Moriduri

Смежные вопросы