简体   繁体   中英

Reading integers from a file

Using the feof() function, on my output file i have the last value printed twice. How can i avoid that? My output should be

12
6
15
13

and i have

12
6
15
13
13

Thank you!

while(!feof(pfile1))
{       
    sum=0;
    fscanf(pfile1,"%d%d%d",&choice,&day,&val);
    if(choice==0)
    {
        i=day-1;
        a[i]=a[i]-val;
    }
    else if(choice==1)
    {
        for(i=day-1;i<=val-1;i++)
        {
            sum=sum+a[i];

        }
        fprintf(pfile2,"%d\n",sum);     
    }
}

That's because the feof flag will only be set, as soon as you read PAST the end of a file. To remedy this problem, replace the feof with the fscanf from below and check for the number of arguments.

If it's lower than 3, you know that some error occurred...for example the end of file was reached.

In fact, you should avoid using feof for the above mentioned reason whenever possible.

To underline this with some code:

while(fscanf(pfile1,"%d%d%d",&choice,&day,&val) == 3) {
    //Continue reading
}
fclose(pfile1);
fclose(pfile2);

The posted code will not detect feof() until after it has processed an unsuccessful read, resulting in the behaviour you witness.

You need to check feof() immediately after the call to fscanf() or check the result of fscanf() which returns the number of assignments made:

if (3 == fscanf(pfile1,"%d%d%d",&choice,&day,&val))
{
    /* All three integers successfully read. */
}

Another possible structure of the loop (as suggested in the comments by MichalAnderson):

while (3 == fscanf(pfile1,"%d%d%d",&choice,&day,&val))
{
}

One option is to check the return value of fscanf :

On success, the function returns the number of items successfully read. This count can match the expected number of readings or be less -even zero- in the case of a matching failure. In the case of an input failure before any data could be successfully read, EOF is returned.

So, something like:

if( fscanf(pfile1,"%d%d%d",&choice,&day,&val) <= 0 )
{
    break;
}

The other option is to check for feof after executing fscanf . For example:

if( feof( pfile1 ) )
{
    return; // or something
}
do
{
    // the same loop body
}
while( ! feof( pfile1 ) );

You should check the number of read elments, as returned by fscanf : if it's not what you're waiting for (3), you should break from the loop.

In this case, you're simply working two times on the last read line.

From the documentation :

RETURN VALUE

Upon successful completion, these functions shall return the number of successfully matched and assigned input items;

fscanf(pfile1,"%d%d%d",&choice,&day,&val);

Here you are reading the integers from an input file. fscanf will scan the file until it reaches the EOF. Each time it reads three integers it returns 3 . If the value returned by fsacnf is less than 3 then it automatically assignes the buffer value. SO this is the reason for getting the repeated value in the output.

If the program is edited with checking the return value of fscanf() for value 3 and then executing the if else statement in regard of choice will give the desired output.

Example 1:-

Consider the input file with content:-

0 2 3

1 1 2

(--blank--) //here the fscanf will scan for an integer but since its a blank line it will reach the EOF , and returns -1 and uses the buffer value (previous values)

Then the output file :-

118

118

Example 2:-

Input File (without blank lines):-

0 2 3

1 1 2

Output File:-

118

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM