2016-05-17 6 views
1

У меня есть функция, которая должна читать символ файла char и выводить на консоль, пока не достигнет EOF. Функция отлично работает, отображая все нужные мне символы, но затем она просто продолжает двигаться и никогда не останавливается в конце.Ошибка функции с EOF

Ниже функция

void displayAllLines(ifstream &joke) 
{ 
    char ch; 
    joke.clear(); 
    ch = joke.get(); 
    while (ch != EOF) 
    { 
     cout << ch; 
     ch = joke.get(); 
    } 
} 

Содержимое файла перечислены ниже

"(пустая строка) Q: Что язык сказать зубы?"

Как я уже говорил, он отображает линию просто отлично, но цикл продолжает идти после вопросительного знака.

Любые мысли о том, почему это может быть? Кроме того, больше информации, необходимой для правильного ответа на мой вопрос?

ответ

1

канонический способ сделать это:

void displayAllLines(ifstream &joke) 
{ 
    char ch; 
    while (true) 
    { 
     ch = joke.get(); 
     if (joke) { 
      cout << ch; 
     } else { 
      break; 
     } 
    } 
} 

Выражение joke будет вычисляться правда, пока не достигнет EOF. Я не уверен, почему вы хотите сначала позвонить joke.clear().

+1

Это просто привычка, которую я учил, когда начинал с файла. Просто убедитесь, что на нем нет флажков в начале. Считаете ли вы, что это бессмысленно, или вы думаете, что это может быть вредно для программы? EDIT :: Что касается кода, который вы отправили, он, безусловно, продвигает программу дальше, но не учитывает пробельные символы и отображает все без пробелов. – Podo

+0

Также интересно, если у вас есть мысли, почему мой код * не делает * Работа. – Podo

+0

Ii не думайте, что вы должны вслепую называть 'clear()' '. Если установлены флаги, то это будет по какой-то причине, и просто очистка их не поможет. Ваш код не работает, потому что потоки C++ не читают EOF как символ, как C. Потоки C++ читают символы, пока они не попадут в EOF. (Они никогда не возвращают символ EOF - это вещь C.) – Phil

1

@Phil ответил «как это сделать на C++». Мой ответ гласит: «Почему это происходит» и «как это сделать в C» (он все еще работает на C++).


Поскольку таблица ASCII проходит весь путь от 1 и мы имеем значение байта 0 ('\0') зарезервирован для терминации строки (языки говорить C и C++), то EOF должно быть особое значение вне из этого.

Именно поэтому getchar(), а также ifstream::get() return a int, а не char. Так что все, что вам нужно сделать, это изменить

char ch; 

в

int ch; 

и брось на символ для печати:

cout << (char) ch; 

Технически EOF обычно -1. Ваш char может иметь дальность 0 - 255, что означает, что он никогда не будет равен -1. Хороший компилятор с включенным -Wall должен дать вам хотя бы предупреждение.

+0

В более общем плане вместо' int' использовать 'std :: istream :: traits_type :: int_type'. Это работает для всех кодировок символов, а не только для ASCII. –

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