-1

why does read() on a file in linux add a newline character at EOF even if the file really does not have a newline character ?

my file data is :

1hello2hello3hello4hello5hello6hello7hello8hello9hello10hello11hello12hello13hello14hello15hello

my read() call on this file should hit EOF after reading the last 'o' in "15hello". I use the below :

while( (n = read(fd2, src, read_size-1)) != 0) // read_size = 21
{
    //... some code
    printf("%s",src);
    //... some code
}

where fd2 is the file's descriptor. At the last loop, n was 17 and i had src[16] = '\n'. So......, does the read call in linux add a newline at EOF?

jww
  • 97,681
  • 90
  • 411
  • 885
Jayanth
  • 115
  • 1
  • 11
  • 1
    You should probably show the output of `cat -n data.txt` in your question. Also see [How to use read() to read data until the end of the file?](https://stackoverflow.com/q/3180126/608639) and [How to use EOF to run through a text file in C?](https://stackoverflow.com/q/1835986/608639) – jww Jun 10 '18 at 15:41
  • `hd` will show you what exactly is in your file, by presenting the character codes in hexadecimal. (Some people prefer `od` -- octal dump.) `man hd` for more info. – rici Jun 10 '18 at 17:02
  • @jww : $ cat -n testdoc2.txt 1 1hello2hello3hello4hello5hello6hello7hello8hello9hello10hello11hello12hello13hello14hello15 – Jayanth Jun 10 '18 at 18:36
  • @rici : it shows a dot at the end. and for the dot, it gives the hex value 0a |lo14hello15.| – Jayanth Jun 10 '18 at 18:39
  • The `0a` at the end is a newline character. So it was in the file all the time. `man ascii` if you need a table. – rici Jun 10 '18 at 18:41
  • rici : got it. thank you rici :) . I will have to figure out why that newline gets in somehow. – Jayanth Jun 10 '18 at 18:42
  • @Jayanth If you're using a text editor to create the input file, depending on which one you're using, it can be difficult or impossible to create a file without the trailing newline. – Steve Summit Jun 10 '18 at 21:14
  • Thank you Steve. Looks like its the text editor. My question does look incorrect to me. – Jayanth Jun 17 '18 at 08:36

2 Answers2

1

does the read call in linux add a newline at EOF?

No.

Your input file likely has a terminating newline in it - most well-formatted text files do, so multiple files can be concatenated without lines running together.

You could also be running into a stray newline character that was already in your buffer, because read() does not terminate the data read with a NUL character to create an actual C-style string. And I'd guess your code doesn't either, else you would have posted it. Which means your

printf("%s",src);

is quite likely undefined behavior.

Andrew Henle
  • 32,625
  • 3
  • 24
  • 56
  • read() does not add a '\0' at the end. Even if I do not add a '\0', I see that when I allocate char str[30], the first 30 characters are all '\0' values by default. Created this test file using a C++ code which does not print a '\n' at the end. I open the file in gedit to make small edits but neither I nor gedit would add any newlines to it. I am confused too, because the man page for read() does not mention newlines. And, the question here is about the newline (not the '\0'). – Jayanth Jun 10 '18 at 18:13
  • @Jayanth You have misunderstood Andrew Henle's comments. He's saying that because `read` does not add a `'\0'`, but `printf("%s"` expects one, `printf` could be reading past the end of the `n` characters read by `read` and finding a stray `\n` character somewhere in random memory off to the right of the `src` array. – Steve Summit Jun 10 '18 at 21:10
  • @Jayanth Also, you said "when I allocate char str[30], the first 30 characters are all '\0' values by default", but depending on how and where you allocated `str`, the 0-fill is necessarily guaranteed; you might have gotten that result by accident. – Steve Summit Jun 10 '18 at 21:11
0

why does read() on a file in linux add a newline character at EOF even if the file really does not have a newline character ? No, read() system call doesn't add any new line at end of file.

You are experiencing this kind of behavior because may be you have created text file using vi command and note that default new line gets added if you have created file using vi.

You can validate this on your system by creating a empty text file using vi and then run wc command on that.

Also you can read file data using read() system call all at once if you know the file size(find size using stat() system call) and can avoid while loop.

This

while( (n = read(fd2, src, read_size-1)) != 0) { 
   /* some code */
}

Change to

struct stat var;
stat(filename, &var); /* check the retuen value of stat()..having all file info now */
off_t size = var.st_size;

Now you have size of file, create one dynamic or stack array equal to size and read the data from file.

char *ptr = malloc(size + 1);

Now read all data at once like

read(fd,ptr,size);/*now ptr having all file contents */

And at last once work done, Don't forgot to free the ptr by calling free(ptr).

Achal
  • 11,821
  • 2
  • 15
  • 37
  • 1
    `stat(fd,&var);` is wrong. That should be `fstat( fd, &var );` `int size = var.st_size;` is also wrong, as [the `st_size` field of a `struct stat` is of type `off_t`.](http://pubs.opengroup.org/onlinepubs/009695399/basedefs/sys/stat.h.html) – Andrew Henle Jun 10 '18 at 16:16
  • Agree @AndrewHenle Let me modify it. – Achal Jun 10 '18 at 16:17