Summarizing the responses so far, and adding my own observations:
You should check the return value from open()
and read()
. If they fail, you're going to blindly continue on and print garbage.
read()
returns the number of characters read, or -1 in case of error. It does NOT null-terminate its buffer, so using strlen()
to find the amount of data read is wrong.
You shouldn't put a call to strlen()
in the loop test condition, since you'll be re-evaluating it each iteration.
The casting of buf[i]
to int
in the printf
statement is unnecessary. The extra arguments to variadic functions such as printf
(that is, all of the arguments that make up the ...
) undergo default argument promotion as follows:
char
s, short
s, and their unsigned counterparts are promoted to int
s
float
s are promoted to double
s
Without a cast, buf[i]
would get implicitly promoted to an int
anyways, so adding the cast, while correct, makes the code more confusing to anyone reading it.
So, your code should look like this:
int fd = open("test.txt",O_RDONLY);
if(fd < 0)
{
fprintf(stderr, "open failed: %s\n", strerror(errno));
return;
}
char buf[128];
// It's better to use sizeof(buf) here, so we don't have to change it in case we
// change the size of buf. -1 to leave space for the null terminator
int reader = read(fd,buf,sizeof(buf)-1);
if(reader < 0)
{
fprintf(stderr, "read failed: %s\n", strerror(errno));
close(fd);
return;
}
buf[reader] = 0; // add null terminator for safety
int i;
for (i=0; i < reader; i++)
{
printf("%i: I read: %c", i, buf[i]);
}