C - does read() add a '\0'?

5.6k views Asked by At

Does it have to? I've always been fuzzy on this sort of stuff, but if I have something like:

char buf[256];
read(fd, buf, 256);

write(fd2, buf, 256);

Is there potential for error here, other than the cases where those functions return -1?

If it were to only read 40 characters, would it put a \0 after it? (And would write recognize that \0 and stop? Also, if it were to read 256 characters, is there a \0 after those 256?

4

There are 4 answers

1
alk On BEST ANSWER

does read() add a '\0'?

No, it doesn't. It just reads.

From read()'s documentation:

The read() function shall attempt to read nbyte bytes from the file associated with the open file descriptor, fildes, into the buffer pointed to by buf.


Is there potential for error here, other than the cases where those functions return -1?

read() might return 0 indicating end-of-file.

If reading (also from a socket descriptor) read() not necessarily reads as much bytes as it was told to do. So in this context do not just test the outcome of read against -1, but also compare it against the number of bytes the function was told to read.


A general note:

Functions do what is documented (at least for proper implementations of the C language). Both your assumptions (autonomously set a 0-termination, detect the latter) are not documented.

0
autistic On

Does it have to?

Not unless the data that is successfully read from the file contains a '\0'...

Is there potential for error here, other than the cases where those functions return -1?

Yes. read returns the actual number of bytes read (or a negative value to indicate failure). If you choose to write more than that number of bytes into your other file, then you are writing potential garbage.

0
Richard On

No.

Consider reading binary data (eg. a photo from a file): adding extra bytes would corrupt the data.

0
DevSolar On

From the man page:

Synopsis

#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);

That is void *, not char *, because read() reads bytes, not characters. It reads zero bytes as well as any other value, and since blocks of bytes (as opposed to strings) aren't terminated, read() doesn't.