Reputation: 464
Look here, those two programms should be equivalent in my opinion. But obviously they aren't, as the first programm works and the second doesn't. Can someone explain to me, why fgets() doesn't do the job?
// FIRST PROGRAM : WORKS FINE
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *stream;
char fileName[67];
scanf("%s", fileName);
printf("%s", fileName);
stream = fopen(fileName, "r");
char ch;
if(stream){
ch = fgetc(stream);
while(!feof(stream)){
putchar(ch);
ch = fgetc(stream);
}
fclose(stream);
}
}
// SECOND PROGRAM: DOES NOT WORK
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *stream;
char fileName[67];
fgets(fileName, 67, stdin);
printf("%s", fileName);
stream = fopen(fileName, "r");
char ch;
if(stream){
ch = fgetc(stream);
while(!feof(stream)){
putchar(ch);
ch = fgetc(stream);
}
fclose(stream);
}
}
I enter "test.txt" into the console both times and press enter then. Of course test.txt exists in the right directory
Upvotes: 0
Views: 237
Reputation: 145297
The main problem you experienced is correctly solved by Weather Vane, but I want to point another problem with your code: the loops for reading and writing the contents of the file are incorrect. Testing the end of file with feof(stream)
leads to incorrect behaviour most of the time. In your case, a read error from stream
will cause your program to loop endlessly, writing 0xFF
bytes to stdout
.
There is a much simpler and idiomatic way to implement this loop:
if (stream) {
int ch;
while ((ch = fgetc(stream)) != EOF) {
putchar(ch);
}
fclose(stream);
}
As you can see, it is simpler and correctly tests for EOF
at the right time, when input fails. It stores the return value of fgetc()
into an int
variable capable of holding all possible return values from fgetc()
. Using an int
is necessary because comparing a char
value to EOF
either always fails if the char
type is unsigned or potentially gives false positives if char
is signed and has value '\377'
.
Upvotes: 1
Reputation: 34583
The reason is that fgets()
retains the newline
entered. You can verify it is there by altering your print statement to
printf("[%s]", filename);
when the ]
will appear on the next line. You can remove the trailing newline
like this
#include <string.h>
...
filename [ strcspn(filename, "\r\n") ] = 0;
Upvotes: 4