About reading file in c [duplicate] - c

This question already has answers here:
Why is “while( !feof(file) )” always wrong?
(5 answers)
Closed 7 years ago.
So i just got an assigment from my prof to make a program that would read or write a file . And i got some problem when reading an empty file , whenever i read an empty file it would input a space character and 0.0 . So is there any way to
Handle this ?
Here is my read code
void read()
{
n = 0 ;
FILE *f ;
f = fopen("namafile.txt","r");
if (f)
{
while (!feof(f))
{
fscanf(f,"%[^|]|%[^#]#%f\n", mhs[n].nim, mhs[n].nama, &mhs[n].x) ;
n++ ;
}
}
else
{
printf("file not found\n");
}
fclose(f) ;
}

The EOF marker will be set after fscanf() fails, so you need a failing fscanf() in order for the loop to end. Also, you have to check if fscanf() succeeded for which you check it's return value, that said all you need is to change this
while (!feof(f))
to
while (fscanf(f,"%[^|]|%[^#]#%f\n", mhs[n].nim, mhs[n].nama, &mhs[n].x) == 3)
NOTE: Don't use identifiers like f, that's a bad habit that you can porbably justify if your IDE has no autocomplete feature, but it's hardly the case, you can name your identifier file instead to make it clear what it is.

Related

What could have possibly gone wrong? fopen bug [duplicate]

This question already has answers here:
Why does printf not flush after the call unless a newline is in the format string?
(10 answers)
Closed 5 years ago.
I have the following snippet of code at the beginning of my program:
printf("Starting extraction of file %s \n", tarName);
// Open the tarFile
FILE* tarFile = fopen(tarName, "r");
if(tarFile == NULL) return EXIT_FAILURE;
// Read nFiles
printf("Reading header...");
...
When I execute it from the terminal I get the following output:
Starting extraction of file test.mytar
And then the program freezes, apparently never reaching the second printf.
test.mytar is an existing file in the same folder as my executable, and this is the same folder from where I am executing the terminal.
The file was created by me byte a byte, so it could possibly be violating file conventions I am not aware of.
What could possibly be going on here?
As pointed out in the comments, two things may happen.
a) the fopen fails (IO error, permission denied, missing file, ...). To know the exact cause, you need to print the errno (or GetLastError() on Windows) :
if(tarFile == NULL) {
printf("%s\n", strerror(errno));
return EXIT_FAILURE;
}
b) the fopen succeeds but printf("Reading header..."); does not show up anything because the message is buffered and not yet printed. To correct this, you can generally add a '\n' at the end of the message.

file name contains spaces can't open with fopen [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I'm writing a program which counts how many times each C keyword is contained in an ASCII file selected by the user. So I use scanf to save the name that the user selected as filename and check with fopen if a file with that name exists in the same dir as the C program. The problem lies in the fact that if the filename selected by the user contains spaces fopen gives an error because it can't find such a file. So here's the question, how do I open a file with fopen that contains spaces in the name of it? Here is the code that i used for the program
selectfilename(filein,1) ;
if (fopen(filein,"r") == NULL){
perror("Error ") ;
return (1) ;
}
void selectfilename(char *cp, int num){
if (num == 1) printf("Please select the name of the file to be opened including the extension : ") ;
else printf("Please select the name of the file to save the statistics including the extension : ") ;
scanf("%s",cp++) ;
}
I think your problem is with scanf, not fopen – which handles filenames with spaces just fine.
scanf("%s") only parse until the first space. It's hard to propose a fix without seeing more of the code.
Update:
Since you read from stdin you can try this to read until the line terminator.
char buf[256];
int rv = scanf ("%255[^\n]", buf); // 255 is max chars to read
if (rv == 0 || rv == EOF)
buf[0] = 0;
printf ("[%s]\n", buf);
Update 2: Fixed bugs reported by #chux

fflush(FILE *stream) not working? [duplicate]

This question already has an answer here:
need of fseek() in c
(1 answer)
Closed 8 years ago.
while(1)
{
ch=fgetc(ft);
if(ch==EOF)
{
break;
}
if(ch=='u')
{
fputc('b',ft);
fflush(ft);
}
}
I tried to replace character after u with b in a file pointed by *ft.
This code runs fine but when I open the file it seemed to be unedited.
The above code works fine with fseeks(ft,0,SEEK_CUR).
Why it is not working with fflush(ft).
fflush only flushes output stream. Hence you need to put fseek(ft,0,SEEK_CUR) above your fputs(ft)

feof() on Linux return true at one line later than the ending line [duplicate]

This question already has answers here:
Why is “while( !feof(file) )” always wrong?
(5 answers)
Closed 9 years ago.
I'm a beginner of C. When I use this while loop to print the contains of a file. The last line will print twice on Linux. It should not get into while loop when reach the end of file. It has no problem on windows.
#include <stdio.h>
#include <unistd.h>
int main()
{
char string[400];
FILE *file_para;
// Open the file
if ((file_para = fopen("Test.txt", "r")) == NULL)
{
printf("cannot open file\n");
getchar();
return 0;
}
while (!feof(file_para))
{
fgets(string, 400, file_para);
printf("**** %s", string);
}
fclose(file_para);
getchar();
return 0;
}
This is the wrong way to use feof(). Use feof() to detect what went wrong after one of the main I/O functions failed. It does not predict whether you're about to reach EOF; it tells you when some I/O function has already reported EOF. C is not Pascal; in Pascal, you can (must?) check for EOF before calling the I/O functions.
while (fgets(string, sizeof(string), file_para) != 0)
{
...do printing, etc...
}
// If you need to, use `feof()` and `ferror()` to sort out what went wrong.
If you really, really insist on using feof(), then you also need to check your I/O operation:
while (!feof(file_para))
{
if (fgets(string, sizeof(string), file_para) == 0)
break;
...do printing, etc...
}
Note that you might be failing because ferror(file_para) evaluates to true even when feof(file_para) does not...so maybe you need while (!feof(file_para) && !ferror(file_para)), but that really is just more evidence that the while loop should be conditioned on the I/O function, not feof().
This is a common anti-pattern:
while (!feof(file_para))
{
fgets(string, 400, file_para);
feof() does not detect if the next input call will fail due to end-of-file; it tells you if the file has already reached end-of-file. You should only call it after an input function has already failed, to see why it failed (which could be either an error or end-of-file).
The correct pattern is:
while (fgets(string, 400, file_para))
{

Extra Loop with EOF [duplicate]

This question already has answers here:
Why is “while( !feof(file) )” always wrong?
(5 answers)
Closed 9 years ago.
I have a problem using the function feof, this is my code:
while(!feof(archlog))
{ if(!fgets(line,MAXLINE,archlog))
printf("\nERROR: Can't read on: %s\n", ARCHTXT);
else
printf("%s",line);
}
When I run this, it prints the text of the file but makes an extra loop and prints the ERROR, I want to avoid this, I want it to only print the text of the file without the extra loop.
The loop will enter once more if the file ends with a new line.
A warkaround whould be:
while(!feof(archlog))
{ if(!fgets(line,MAXLINE,archlog))
printf("\nERROR: Can't read on: %s\n", ARCHTXT);
else
printf("%s",line);
if ( (c=fgetc(archlog)) == EOF)
break;
ungetc(c, archlog);
}
The EOF flag is set once your gets function reads the EOF. This means that the last iteration will always trigger the error message. After this, the loop tests for the EOF flag again, which was triggered on the last read and thus exits the loop.
You could get around this by placing the EOF test inside the loop. There you can either print the text on a successful read or set a boolean to exit the loop if there is a failure.
I always reverse the two function calls:
while(fgets(line,MAXLINE,archlog))
{ if(feof(archlog))
break;
else
printf("%s",line);
}
That gets me out when the end of file is read. Sometimes I 'or' in ferror(archlog) to the feof() call, to break out on error or EOF.
You should not use feof(FILE *f) in your loops as it returns true only if EOF is read, not reached, see How to use feof(FILE *f)?
Instead use fgets and its return code for the condition:
while(fgets(line, MAXLINE, archlog) != NULL) {
printf("%s", line);
}
There is no need for checking feof(archlog) inside the loop. For error checking use ferror(archlog).

Resources