Вопросы о EOF и EOL - PullRequest
       11

Вопросы о EOF и EOL

1 голос
/ 25 июля 2011

Я пытаюсь понять EOF и EOL, и как на самом деле работает iostream на C ++.

Принимая ввод через getchar() или getche() в переменную char, я обнаружил, что если янапишите такие строки, как:

char a;
a =  getche();  // it returns char '\r' if pressed enter
a =  getchar(); // it returns char '\n' if pressed enter

Почему эти значения?

  1. Что на самом деле заставляет C ++ думать, что мы исчерпали ввод ( т.е. всегда ли это *)1014 * что заставляет C ++ думать, что он находится в конце своего ввода? ).

  2. При чтении / записи файла, в котором есть строковые предложения, заканчивающиеся на '\n', что тогдапроисходит, если строки заканчиваются символом NULL, который также представляет конец строки?

Не могли бы вы кратко объяснить все это на примерах?

Ответы [ 3 ]

4 голосов
/ 25 июля 2011

При вводе через getchar() или getche() в char переменная, я обнаружил, что если я напишу строку как:

char a; a = getche(); // it returns char '\r' if pressed enter
a = getchar();        // it returns char '\n' if pressed enter

Во-первых, getche - это функция POSIX из conio.h, которая является нестандартной и не рекомендуется во всех основных наборах инструментов.

Это небуферизованная, неформатированная операция чтения. Когда ваш входной поток использует \r\n для окончания строки (обычно в Windows), тогда вы читаете этот первый символ \r.

Когда вы затем выполняете getchar(), вы получаете второго персонажа, \n. Это тоже функция C.

Остальная часть моего ответа будет о C ++.

Что на самом деле заставляет С ++ думать, что мы не будем предоставлять никакой информации (то есть всегда \ n, что заставляет c ++ думать, что это конец ввода?).

Буферизованные функции ввода / вывода имеют тенденцию ограничивать чтение по \n, да. В std::getline имеется параметр, который позволяет изменить этот разделитель:

std::istream& std::getline(std::istream& is, std::string& str);
std::istream& std::getline(std::istream& is, std::string& str, char delim);

Но это всего лишь разделитель. Вы можете считать, что это означает «Конец строки», но это определенно не «Конец файла».

Во время чтения / записи файла (в котором заканчиваются некоторые строковые предложения с \ n. тогда что, если строки заканчиваются нулевым символом, который также представляет конец строки?).

Нулевые символы не имеют значения.

Единственная проблема, связанная с нулевыми символами, - это строки буфера в стиле C char без дополнительной информации о длине. Единственный способ определить длину строки заключается в поиске завершающего нулевого символа (см .: strlen), что проблематично, если в полезной части разбросаны произвольные другие нулевые символы данных.

Если вы передаете указатель на массив char и его размер как int, тогда он может содержать столько нулевых символов, сколько вам нужно.

При чтении символов из потока, в C или C ++, используемая вами функция сообщает, сколько символов было прочитано. Так что, даже если некоторые из них были нулевыми символами, это не имеет значения. Вы можете обращаться с ними так, как считаете нужным.

что символ представляет конец строки при записи / что символ представляет конец ввода строки при чтении?

Я не совсем понял этот вопрос, но я завершу свой ответ кратким описанием End Of File.

Исторически файлы имели физический символ \004 (^D), который находился в конце своего содержимого и представлял конец файла.

В настоящее время этот физический символ не используется таким образом, но внутренние компоненты ОС и файловой системы будут использовать различные механизмы для информирования вашего приложения о том, что больше нет ввода . Функции C возвращают макрос EOF, а объекты C ++ имеют флаг состояния, который вы можете проверить.

Детали того, как именно это работает, отвлечены от вас; ты не должен заботиться об этом.

Интересно, что для завершения ввода в консоли Linux все равно нужно нажимать на клавиатуре ^D.


Надеюсь, это вам чем-то помогло. Ваш вопрос не был особенно ясен, но вышеизложенное предназначено для краткого описания EOL и EOF в C ++.

Я могу порекомендовать эти книги и ресурсы для дальнейшего чтения.

1 голос
/ 25 июля 2011

Вы смешиваете C и C ++.

Путь C ++ выглядит следующим образом: :

std :: string input;
while (std :: getline (input_stream, input)) {
     // Do stuff
}

std::getline возвращает input_stream, что приводит к логическому значениюложь, когда ввод заканчивается или что-то еще не удается.Здесь «заканчивается» означает «встречает EOF» или какое-либо аналогичное условие.

Вы также можете выполнить

std :: string input;
while (std :: getline (input_stream, input, delimiter)) {
     // Do stuff
}

, если по умолчанию '\n' не является правым ограничителем строки.

EOF - это специальное значение ASCII , которое является историческим, относится к ранним протоколам принтеров и взломам терминалов и теперь имеет значение только при использовании getchar или других подобных антиквариатов.

'\n' - стандартный символ конца строки UNIX.Microsoft использует "\r\n", что является двумя инструкциями для принтера: переместите головку в начало строки и переместите бумагу вверх на строку.UNIX решила, что нет никаких причин продолжать этот путь в мир непечатных файлов, и отбросила '\r'

0 голосов
/ 25 июля 2011

getchar и getche должны получать по одному символу за раз.Не должно быть понятия «конец линии».Если вы заканчиваете свою строку символом NULL, вы должны вернуть его как прочитанный вами символ.

Когда прочитан конец файла, вы получите специальный макрос EOF в качестве возвращаемого значения.Сопоставьте это, чтобы определить конец файла.Если вы получили '\ n' или NULL, вы можете разобрать его в соответствии с вашим файлом (то есть обработать как конец строки текста).

http://www.cplusplus.com/reference/clibrary/cstdio/getchar/

(не уверен, что я когда-либо использовал это) http://msdn.microsoft.com/en-us/library/kswce429(v=vs.80).aspx

...