Чтение входных данных из файла на C

#c #file #fgets

#c #файл #fgets

Вопрос:

Я наткнулся на следующий вопрос:

Если файл содержит строку «Я мальчик r n», то при чтении этой строки в массив str с помощью fgets() . Что будет содержать str?

  • [A]. «Я мальчик r n 0»
  • [B]. «Я мальчик r 0»
  • [C]. «Я мальчик n 0»
  • [D]. «Я мальчик»

Ответ был дан как вариант c с объяснением

Объявление: char * fgets(char * s, int n, FILE *stream);

fgets считывает символы из потока в строку s. Он останавливается, когда считывает либо n — 1 символов, либо символ новой строки, в зависимости от того, что наступит раньше.

Однако я не мог понять, как r (возврат каретки) повлияет на fgets. Я имею в виду, не должно ли быть так, что сначала читается «я мальчик», затем при обнаружении r курсор устанавливается в исходное положение, а «I» из «I am a body» перезаписывается на n, а пробел после «I» перезаписывается на .

Любая помощь будет высоко оценена.

P.s: Мое утверждение основано на объяснении, приведенном по этой ссылке: https://www.quora.com/What-exactly-is-r-in-the-C-language

Ответ №1:

Во-первых, каждый раз, когда вы видите тест с несколькими вариантами ответов на каком-нибудь программном сайте, я рекомендую вам закрыть вкладку и вместо этого заняться чем-нибудь продуктивным, например, просмотром видео с котятами. Потому что вопросы, по-видимому, представляют собой лишь некоторые варианты

Какая из них является первой буквой алфавита (правильна только одна)

  1. A
  2. a
  3. 6
  4. a
  5. буква a
  6. все вышеперечисленное.

Возврат каретки и перевод строки не влияют таким образом на входные данные, считываемые программой на C. Каждый дополнительный байт находится поверх других байтов. В противном случае это очень плохо сформулированный вопрос, так как ответом может быть любой из A, B, C или D, а может быть, ни один из них. Утверждение, что C является единственным правильным, неверно.

Первый вопрос: что это значит, если «файл содержит r «? Здесь я предполагаю, что автор имел в виду, что файл содержит 10 символов I am a boy , за которыми следуют ASCII 13 и ASCII 10 (возврат каретки и перевод строки).

В C есть два режима перевода для чтения файлов: текстовый режим и двоичный режим. В системах POSIX (во всех операционных системах с X в их имени, за исключением исключения Windows) они равны — текстовый режим игнорируется. Поэтому, когда вы читаете строку в буфер с fgets помощью on POSIX, он будет искать этот перевод строки и сохранять все буквы как есть, включая the , поэтому буфер будет иметь следующую последовательность байтов I am a boyrn . Следовательно, A может быть true .

Но в Windows текстовый режим преобразует возврат каретки и перевод строки в один символ новой строки со значением ASCII 10 в памяти, так что у вас будет I am a boyn . Поэтому C может быть true. Если ваш файл был открыт в двоичном режиме, у вас все равно будет I am a boyrn — так как же вы утверждаете, что C является единственным, который может быть истинным?

Если строка, которую вы прочитали, fgets будет I am a boyrn (POSIX или двоичный режим), но вы сказали fgets , что в вашем буфере есть место только для 12 символов, тогда вы получите 11 символов ввода и завершения , и, следовательно, у вас будет I am a boyr . Символ возврата каретки останется в потоке. Следовательно, B может быть true . B не может быть истинным, если вы указали, что в буфере будет больше места.

Наконец, любое из этих содержимого массива содержит строку I am a boy , поэтому D будет истинным во всех приведенных выше случаях.

И если в вашем буфере недостаточно места для 10 символов и терминатора, тогда у вас будет некоторый префикс содержимого, например, I am a bo за которым следует, что означает, что ни одно из них не было истинным.

Комментарии:

1. Вы когда-нибудь читали файл, открытый в двоичном режиме с помощью fgets?

2. @klutt почему бы и нет… не уверен, что я хотел бы использовать текстовый режим для чего-либо: D

3. что будет делать r в Windows? Я имею в виду, не приведет ли это курсор к первой позиции.