I’m having a hard time trying to figure out why this piece of code doesn’t work as it should. I am learning the basics of I/O operations and I have to come up with a C program that writes on a ‘log.txt’ file what is given from standard input and as the ‘stop’ word is entered, the program must halt.
So my code is:
#include "main.h"
#define SIZE 1024
int main(int argc, char *argv[])
{
int fd;
int readBytes;
int writBytes;
char *buffer;
if ((fd = open("log.txt", O_WRONLY|O_APPEND)) < 0)
{
perror("open");
}
buffer = (char *) calloc (SIZE, sizeof(char));
while ((readBytes = read(0, buffer, SIZE) < SIZE)&&(strncmp(buffer, "stop", 4) != 0));
if ((writBytes = write(fd, buffer, SIZE)) < 0)
{
perror("write");
}
if ((close(fd)) < 0)
{
perror("close");
}
}
If I enter:
this is just a text
stop
The output is
stop
is just a text
If I enter more than a sentence:
this is just a text
this is more text
and text again
stop
This is what is logged:
stop
ext again
xt
t
And on top of that if I try to edit the log.txt file from vim or just a text editor I can see ‘\00’s. I guess \00 stands for all the bytes left empty from the 1024 available, right? How can I prevent that from happening?
It looks like you’re expecting
to somehow accumulate things in buffer. It doesn’t. Every subsequent
readwill put whatever it read at the start of the buffer, overwriting what the previousreadhas read.You need to put your
writein thewhileblock – one write for every read, and onlywriteas much as youread, otherwise you’ll write garbage (zeros from thecallocand/or leftovers from the previous read) in your log file.Also note that while your technique will probably work most of the time for a line-buffered input stream, it will not do what you expect if you redirect from a file or a pipe. You should be using formatted input functions (like
getlineif you your implementation has that,scanf, orfgets).