2
votes

I am trying to read 1 line and I am not sure how newline char is represented. Should I consider it as 2 chars or 1 char, when reading it from file by fgets() ? For example, I have a line of 15 chars + new line in file. So how should I safely allocate string and read that line?

At first, I tried this:

char buf[16];
fgets(buf, 16, f);

It read the line correctly without newline char and I assume that buf[15] holds the null character.

However, when I want to read and store the newline char, it doesn't work as I thought. As far as I know, '\n' should be considered as one char and take just one byte, so to read it, I just need to read one more char.

But when i try this

char buf[17];
fgets(buf, 17, f);

it does completely the same thing than previous example - there is now newline char stored in my string (I am not sure where null char is stored in this case)

To read entire line with newline I need to do this

char buf[18];
fgets(buf, 18, f);

OR this (it works, but I am not sure if it's safe)

char buf[17];
fgets(buf, 18, f);

So the questions is, why do I need to allocate and read 18 chars, when the line has only 15 chars + newline?

2
"it works, but I am not sure if it's safe" <- it isn't safe. If the line is long enough, fgets writes outside the buffer.Daniel Fischer
Can you check the line contents (with the 18 byte buffer and fgets) whether there's a '\r' at position 15?Daniel Fischer
In Windows, newline is two characters: "\r\n".Some programmer dude
on buf[15] there is something with ASCI code 13 (which is probably '\r'), buf[16] holds '\n' and buf[17] is null char. Ok, thanks for help, now I see why I need 2 chars for newline.user10099

2 Answers

1
votes

You need to provide buffer space for the 15-chars of text, up to 2 characters for the new line (to handle Windows line termination of \r\n), and one more for the null termination. So that's 18.

Like you did here:

char buf[18]; fgets(buf, 18, f);

The num parameter to fgets tells the call the size of your buffer it's writing to.

1
votes

I am trying to read 1 line and I am not sure how newline char is represented.

In text mode, newline is '\n' and that's true on any conform C implementation and I wouldn't use fgets on anything but a text mode stream (I don't know -- and I don't want to know -- how it works in binary mode on an implementation using \r as end of line marker, or worse using an out of band end of line marker, I wouldn't be surprised it looks for a \n and never find one thus try to read until the end of file).

You should allocate space for the maximal line length, included the newline plus the terminating NUL and more important you must never lie the fgets about the length of the buffer. You can check if the buffer was long enough as the newline won't be present if it isn't.