0

I've been doing abit of reading through the Linux programmer's manual looking up various functions and trying to get a deeper understanding of what they are/how they work.

Looking at fgets() I read "A '\0' is stored after the last character in the buffer .

I've read through What does \0 stand for? and have a pretty solid understanding of what \0 symbolizes (a null character right ?). But what I'm struggling to grasp is its relevance to fgets(), I don't really understand why it "needs" to end with a null character.

Community
  • 1
  • 1
Spooler
  • 222
  • 1
  • 10
  • 3
    Because fgets() returns a string in C (character array) and those need to be terminated with a \0 character as per C standard. – Magisch Dec 23 '15 at 10:48
  • Because the `'\0'` is required for string handling functions to operate. It marks the end of the array. Remember: you tell `fgets` the size of the buffer, but the string it reads may be shorter than that. – Weather Vane Dec 23 '15 at 10:49
  • read: "I know that a null ends a string. But why does my string end with a null?" – Lightness Races in Orbit Dec 23 '15 at 10:56
  • @LightnessRacesinOrbit more like "I know strings end with `\0`, but why does fgets() also know that?" – Magisch Dec 23 '15 at 10:59
  • @Magisch: "f[ile] get s[tring]" lol – Lightness Races in Orbit Dec 23 '15 at 11:01
  • Ok, ok I get it I'm a dunce. Making a fool of myself helped me better understand what was actually going on with both fgets() and strings in general with C so I'm ok with that :P. Thanks for taking the time to respond ! – Spooler Dec 23 '15 at 11:23

4 Answers4

5

As you already said, you are probably aware that \0 constitutes the end of all strings in C. As per the C standard, everything that is a string needs to be \0 terminated.

Since fgets() makes a string, that string, of course, will be properly null terminated.

Do note that for all string functions in C, any string you use or generate with them must be terminated with a \0 character.

Magisch
  • 7,312
  • 9
  • 36
  • 52
3

Because otherwise you do not know how long the resulting string is.

One of the arguments to fgets is the maximum number of characters to read, but it's just that: a maximum. If you ask for 512 characters, but there are only 8 in the buffer, you will only get 8 characters … and a NULL in the 9th slot to demark the logical end of the C-string.

Arguably, fgets could instead have been designed to return the number of characters read, but then for most purposes you'd only have to add the NULL byte yourself manually, and the function would have to find a way to signify an error other than returning a null pointer.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
0

From C standards:

The fgets function reads at most one less than the number of characters specified by n from the stream pointed to by stream into the array pointed to by s. No additional characters are read after a new-line character (which is retained) or after end-of-file. A null character is written immediately after the last character read into the array.

This is to make sure that there is no buffer-overflow (characters/contents are not going beyond the provided storage) is in the created string.

Pawan
  • 1,537
  • 1
  • 15
  • 19
0

As all the people before me said, fgets reads bytes from a file and makes them into a standard C string, which is null-terminated. The termination with the \0 byte reflects the fact that this function is text-oriented.

If you don't want to use null-termination for the data read from the file, it's not a string (not text), and also the end-of-line byte \n has no significance. In this case, you can use fread.

So C has two functions to read from file: fgets for text and fread for non-text (binary data).

BTW if the input file has a genuine zero-valued byte, fgets will do an uncomfortable thing: it will continue reading until it reads an end-of-line byte \n, and the output "string" will have two (or more) null-terminations. This doesn't make any sense as text, so it's another example of fgets being text-oriented and unsuitable for arbitrary data.

anatolyg
  • 26,506
  • 9
  • 60
  • 134