I am trying to get a basic understanding on how to use fputc in C. I have read some documentation that is out there and believed I had it right. But every time I try to use the script I wrote by executing ./fputc > test.txt where text.txt is a text file with one line of text.
This is my script:
int
main(int argc, char **argv){
int ch;
FILE *input;
input = fopen("text.txt", "w+");
while ((ch = getchar()) != EOF){
fputc(ch, input);
}
fclose(input);
return 0;
}
I get no errors on compilation and for some reason the script does not reach EOF at the end of the text file. Shouldn't the getchar return EOF when it reached the end of the text file? The text (text.txt) file does not appear to be edited, although it is created. So somewhere in my while loop something is going wrong.
I am new to C programming (if you couldn't tell) and this little script has me befuddled.
Any help would be appreciated, or any links to sites with further detail would also be great.
Cheers,
S.
What you in essence say is:
Console: Run my_program and write anything it outputs to test.txt.
Program: Open text.txt and write any input to stdin to that file.
Your console normally have three standard streams stdin
, stdout
and stderr
. These streams you can redirect. If you are on Windows also look at i.e. redirection.
When you say ./my_prog > test.txt
, what you tell your console, (not my_prog
), is to write anything my_prog
writes to stdout
to the file test.txt
.
If you in your code say i.e. printf("Hello");
, then Hello would be written to the file test.txt
.
If you had turned your redirection around by saying ./my_prog < test.txt
instead, would be; stream the file test.txt to my_prog. Which, in turn, if there was any text in test.txt would result in a copy of test.txt to text.txt.
Now in your code you say:
int main(void)
{
int ch;
FILE *input;
/* Here you open a handle to the file text.txt for reading and writing */
input = fopen("text.txt", "w+");
while ((ch = getchar()) != EOF) { /* get next char from stdin */
fputc(ch, input); /* write that char to the handle input */
}
fclose(input); /* close the handle */
return 0;
}
So what happens, the way you run it, is:
In your code:
In console:
my_prog
to test.txt.You say:
the script does not reach EOF
Well, as it reads from stdin
it will only (not without exception) get EOF under two conditions.
If you redirect a file to your program. I.e. ./my_prog < foo.txt
(notice <
, not >
).
- What would happen then is that my_prog
would read the data from the file foo.txt
and when that file ends your program would receive a EOF. And, hence quit.
If you manually enter EOF to stdin
.
- On Linux and OSX Ctrl-D, on Windows Ctrl-Z
Now, if you test this by typing text to console remember that write actions like fputc()
is buffered. What this mean is that the data is not written to the file right away, but only when a given amount of data is in buffer, fflush()
is called, stream is closed, you turn off buffering, etc.
Also; if you run your program. Enter text, enter some more text, and then hit Ctrl-C to abort the program it is a big chance you end with no data in your text.txt
.
The reason for this is that the program is killed and thereby fclose()
never called, and hence no flush to file.
On your further endeavors in programming it would be a very good idea to make a habit of not presuming anything. I.e. do not presume fopen()
is OK.
FILE *fh;
char *outfile = "foo.txt";
if ((fh = fopen(outfile, "w")) == NULL) {
fprintf(stderr,
"Unable to open file %s\n --",
outfile);
perror(" fopen() ");
return 1;
}
Most functions has a way to check if operation was a success. I.e:
if (fputc(ch, fh) != ch) { err ...
This will make your code a lot safer, give you hints on where it fails etc.
Some links: