Reputation: 3
The programm I tried writing should have been able to read a string of a length not longer than 8 characters and check if such string were present in the file. I decided to use 'read' system function for it, but I've come up with a strange behavior of this function. As it's written in manual, it must return 0 when the end of file is reached, but in my case when there were no more characters to read it still read a '\n' and returned 1 (number of bytes read) (I've checked the ASCII code of the read character and it's actually 10 which is of '\n'). So considering this fact I changed my code and it worked, but I still can't understand why does it behave in this way. Here is the code of my function:
int is_present(int fd, char *string)
{
int i;
char ch, buf[9];
if (!read(fd, &ch, 1)) //file is empty
return 0;
while (1) {
i = 0;
while (ch != '\n') {
buf[i++] = ch;
read(fd, &ch, 1);
}
buf[i] = '\0';
if (!strncmp(string, buf, strlen(buf))) {
close(fd);
return 1;
}
if(!read(fd, &ch, 1)) //EOF reached
break;
}
close(fd);
return 0;
}
Upvotes: 0
Views: 108
Reputation: 1718
The read()
function unless it finds a EOF
keeps reading characters and places it on the buffer. here in this case \n
is also considered as a character. hence it reads that also. Your code would have closed after it read the \n
as there was nothing else other than EOF
. So only EOF
is the delimiter for the read()
and every other character is considered normal. Cheers!
Upvotes: 0
Reputation: 98526
I think that your problem is in the inner read()
call. There you are not checking the return of the function.
while (ch != '\n') {
buf[i++] = ch;
read(fd, &ch, 1);
}
If the file happens to be at EOF when entering the function and ch
equals '\n'
then it will be an infinite loop, because read()
will not modify the ch
value. BTW, you are not checking the bounds of buf
.
Upvotes: 1
Reputation: 25199
I'm assuming the question is 'why does read()
work this way' and not 'what is wrong with my program?'.
This is not an error. From the manual page:
On success, the number of bytes read is returned (zero indicates end of file), and the file position is advanced by this number. It is not an error if this number is smaller than the number of bytes requested; this may happen for example because fewer bytes are actually available right now (maybe because we were close to end-of-file, or because we are reading from a pipe, or from a terminal), or because
read()
was interrupted by a signal. On error,-1
is returned, and errno is set appropriately. In this case it is left unspecified whether the file position (if any) changes.
If you think about it read
must work this way. If it returned 0 to indicate an end of file was reached when some data had been read, you would have no idea how much data had been read. Therefore read
returns 0 only when no data is read because of an end-of-file condition.
Therefore in this case, where there is only a \n
available, read()
will succeed and return 1. The next read will return a zero to indicate end of file.
Upvotes: 0