I am trying to read a file given in following format
hello
{
1--2
2--3
3--4
}
I only want to use integers given in the file and to do that i am using the following code
while(fscanf(fp, "%d--%d", &a, &b) != EOF)
{ // do something here}
The problem is that this is not working because it goes in to an infinite loop after reading first line and if i remove first line it goes to an infinite loop at the last line where it read } . So,how can do this in a proper way?
If all else fails, RTFM:
fscanf: "This function return the number of input items successfully matched and assigned, which can be fewer than provided for, or even zero in the event of an early matching failure."
Meanwhile, EOF=-1 although in some stdio.h header files on some platforms it could be equal to zero.
You could either check that fscanf returns 0 or use feof(fp) to check that the end of file has been reached.
Related
I am facing problems looping a fscanf. As in the code below (focus on the part where the while loop starts), I am looping the fscanf until it reached EOF. As you can see from the 2nd part below, the .txt file to fscanf from has only 6 strings,so the fscanf should only loop 6 times and then it reaches EOF. However, as you can see from the program output (2nd part belowe), the fscanf is looped 7 times. Since my program displays the missilenames in reverse order, I assume the while loop looped 1 additional time at the end, resulting at the blank line output on the first line of 3rd picture.
Can someone tell me how to fix this problem pls?
C CODE
while(fscanf(readmissiles,"\n %s \n",missilename)!=EOF)
{
missilename=malloc(20*sizeof(char));
insertvalue(LL,missilename);
missilenum++;
}
TEXT FILE TO FSCANF FROM
single
splash
single
V-Line
h-line
Single
OUTPUT/DISPLAY
/there is a blank line displayed before the Single/
Single
h-line
V-Line
single
splash
single
7
fscanf returns the number of elements scanned or EOF in case of error or end of file is reached before it could match anything. On the last loop fscanf returns 0 - it did not scan the element but it scanned \n, so it returns 0. Do:
while(fscanf(readmissiles, "%s", missilename) == 1)
Loop until there is one element scanned.
When I run the program the last data in the file gets displayed twice.
#include<stdio.h>?//heder
#include<conio.h>//header
int main(){//main
int cn,clas;//variable declaration
char fn[15],ln[15],pn[10],adds[15];//variable declaration
float mr;//variable declaration
int i=1;//variable declaration
FILE *fp;//file pointer declaration
fp=fopen("student.txt","r");// opening a file
if (fopen("student.txt","r") == NULL) {
printf("Error: file pointer is null.");
return 0;
}
while(! feof(fp) ){//here the program reads the data from file
fscanf(fp,"%d",&cn);
fscanf(fp,"%s",&fn);
fscanf(fp,"%s",&ln);
fscanf(fp,"%d",&clas);
fscanf(fp,"%s",&adds);
fscanf(fp,"%s",&pn);
fscanf(fp,"%f",&mr);
//from here the data is printed on output string
printf("%d",cn);printf("\n");
printf("%s",fn);printf("\n");
printf("%s",ln);printf("\n");
printf("%d",clas);printf("\n");
printf("%s",adds);printf("\n");
printf("%s",pn);printf("\n");
printf("%f",mr);printf("\n");
printf("\n");
printf("\n");
}
}
the file i acessed is this
this is the file that i accesed
and the output that the program gives is this
the last one gets repeated
this is output
please help me with this
Normally, this is only worthy of a comment, but in this case it is precisely the root cause of your problem. You are using feof incorrectly. feof does not return true until after a read has failed. So your program reads the last line, then goes to the top of the loop when feof returns false. Then the first scanf fails (and all of them fail), then the printf's are executed with the data that is still available from the previous iteration of the loop, then feof returns true and the loop is terminated. You must check the return value of each scanf and break out of the loop if any of them fail to read data. Or, better yet, avoid scanf, use fread and parse the buffer.
I try to get input from a text file. First line of the text only contains a number, then others related with it like that;
4
ssss
sss
ss
s
I used fgets function for getting these lines from file, but I want to use "4" and the other lines in different functions.
I was getting both these lines with fgets like that;
char inp[150];
int i;
FILE *fp;
while(1) {
if(fgets(inp, 150, fp) == NULL) break;
printf("%s",inp);
i++;
}
I used printf for only see that this code getting all lines or not. It is getting all lines same with input, but when I try to print first line of the input "inp[0]", I expect to print "4", but it prints "s" again.
Therefore, I can't use or get the number which is in the first line. How can I print or use first line independently from others.
By the way, the number and the other lines ,which are related with it, can change with another inputs.
Pass the file pointer to the functions, and have them attempt to read the lines.
That's a basic parser for you.
Don't forget to:
Do error handling, and properly indicate if a read failed.
Reset the file pointer position in case of failure.
Store the result of fgetpos at the beginning and restore it with fsetpos
The problem with your code is that fgets(inp, 150, fp) reads until newline, 149 characters read or EOF.
So each timefgets(inp, 150, fp) you store new values in inp. And last value is s.
Try to use fgetc and store character by character in inp.
I have a text file of composed of sequences of 2 bytes which I have to store in an array.
I have declared FILE *ptr.
How can I loop until EOF without using the method:
while(c = getc() != EOF)
{
// do something
}
I want to implement something along the lines of (PSEUDOCODE):
while (ptr is not pointing to the end of the file)
{
fscanf(...) // I will read in the bytes etc.
}
The getc() method wouldn't work well for me because I am reading in blocks of 2 bytes at a time.
You can use fread to read more than one byte at a time. fread returns the number of items it was able to read.
For example, to read 2-byte chunks you might use:
while ((fread(target, 2, 1, ptr) == 1) {
/* ... */
}
Here 2 is the number of bytes in each "item", and 1 is the number of "items" you want to read on each call.
In general, you shouldn't use feof() to control when to terminate an input loop. Use the value returned by whichever input routine you're using. Different input functions vary in the information they provide; you'll have to read the documentation for the one you're using.
Note that this will treat an end-of-line as a single '\n' character. You say you're reading from a text file; it's not clear how you want to handle line endings. You should also decide what you want to do if the file has an odd number of characters.
Another option is to call getc() twice in the loop, checking its result both times.
The only way to tell when you've reached the end of the file is when you try to read past it, and the read fails. (Yes, there is an feof() function, but it only returns true after you've tried to read past the end of the file.)
This means that, if you're going to use fscanf() to read your input, it's the return value of fscanf() itself that you need to check.
Specifically, fscanf() returns the number of items it has successfully read, or EOF (which is a negative value, typically -1) if the input ended before anything at all could be read. Thus, your input loop might look something like this:
while (1) {
/* ... */
int n = fscanf(ptr, "...", ...);
if (n == EOF && !ferror(ptr)) {
/* we've reached the end of the input; stop the loop */
break;
} else if (n < items_requested) {
if (ferror(ptr)) perror("Error reading input file");
else fprintf(stderr, "Parse error or unexpected end of input!\n");
exit(1); /* or do whatever you want to handle the error */
}
/* ... */
}
That said, there may be other options, too. For example, if your input is structured as lines (which a lot of text input is), you may be better off reading the input line by line with fgets(), and then parsing the lines e.g. with sscanf().
Also, technically, there is a way to peek one byte ahead in the input, using ungetc(). That is, you could do something like this:
int c;
while ((c = getc(ptr)) != EOF) {
ungetc(c, ptr);
/* ... now read and parse the input ... */
}
The problem is that this only checks that you can read one more byte before EOF; it doesn't, and can't, actually check that your fscanf() call will have enough data to match all the requested items. Thus, you still need to check the return value of fscanf() anyway — and if you're going to do that, you might as well use it for EOF detection too.
Hello i have simply function to read from file
while(fscanf(fp," %255[a-zA-Z]",test) == 1)
{
puste = 1;
push(&drzewo,test);
}
It should read only words which contains only alphabetic characters and that works great. When I have for example a single number in my file my while loop quits; how should I change it?
Of course it stops, since the fscanf() call will fail to do the conversion you're requiring, and thus return 0. What would you expect it to do?
It's often better to read whole lines using fgets(), and then parse them "manually", that way it's easy to just do nothing and read another line if the desired data is not found.