简体   繁体   中英

Reading input from a file in C

I came across the following question:

If a file contains the line "I am a boy\r\n" then on reading this line into the array str using fgets(). What will str contain?

  • [A]. "I am a boy\r\n\0"

  • [B]. "I am a boy\r\0"

  • [C]. "I am a boy\n\0"

  • [D]. "I am a boy"

The answer has been given as option c with the explanation

Declaration: char *fgets(char *s, int n, FILE *stream);

fgets reads characters from stream into the string s. It stops when it reads either n - 1 characters or a newline character, whichever comes first.

However, I couldn't understand how will \r (carriage return) influence fgets. I mean, shouldn't it be that first "I am a boy" is read, then on encountering \r cursor is set at the initial position and "I" from "I am a body" is overwritten by \n and space following "I" is overwritten by \0.

Any help is deeply appreciated.

Ps: My claim is based on the explanation given on this link: https://www.quora.com/What-exactly-is-r-in-the-C-language

First, every time you see a multiple choice quiz on some programming website, I recommend you close the tab and do something productive instead such as watching videos of kittens. Because the questions seem to be just some variants of

Which of these is the first letter of the alphabet (only one is right)

  1. A
  2. a
  3. 6
  4. a
  5. the letter a
  6. all of the above .

Carriage returns and line feeds do not affect the input read by a C program in that way. Each additional byte is just on top of the other bytes. Otherwise, this is very badly phrased question, as the answer be any of A, B, C or D, or maybe none of them. Saying that C is the only one that is right is wrong .

First question is what it means if "the file contains \r "? Here I assume that the author meant that the file contains the 10 characters I am a boy followed by ASCII 13 and ASCII 10 (carriage return and line feed).

In C there are two translation modes for reading files, text mode and binary mode. On POSIX systems (all those operating systems with X in their name, except for Windows eXcePtion) these are equal - the text mode is ignored. So when you read the line into a buffer with fgets on POSIX, it will look for that line feed and store all letters as is including the, so the buffer will have the following sequence of bytes I am a boy\r\n\0 . Therefore A could be true.

But on Windows, the text mode translates the carriage return and the linefeed to one newline character with ASCII value 10 in memory , so what you will have is I am a boy\n\0 . Therefore C could be true. If your file was opened in binary mode, you'll still have I am a boy\r\n\0 - so how'd you claim that C is the only one that can be true?

If the string that you'd read with fgets would be I am a boy\r\n (POSIX or binary mode) but you told fgets your buffer has space for only 12 characters, then you'd get 11 characters of the input and terminating \0 , and therefore you'd have I am a boy\r\0 . The carriage return character would remain in the stream. Therefore B could be true. B cannot be true if you indicated that the buffer will have more space.

Finally any of these array contents does contain the string I am a boy , therefore D would be true in all of the cases above.

And if your buffer didn't have enough space for 10 characters and the terminator then you'd have some prefix of the contents, such as I am a bo followed by \0 which means that none of these was true.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM