Thread: Does fflush increment file pointer??

  1. #1
    Registered User
    Join Date
    Aug 2011
    Posts
    385

    Does fflush increment file pointer??

    I am writing a code, and its giving unexpected output, and after some debugging I have found out that a FILE pointer is getting incremented after a call to fflush. Now, fflush is not supposed to change the position of the file pointer, so why could this be happening, any ideas??

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Post the smallest and simplest compilable program that demonstrates the problem. Also, post the input provided, the expected output and the actual output.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Aug 2011
    Posts
    385
    Appears to be a bug in MSVC 2010, the same code runs perfect with Pelles C.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by juice
    Appears to be a bug in MSVC 2010, the same code runs perfect with Pelles C.
    Maybe, but I am more inclined to suspect a bug in your code first.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Aug 2011
    Posts
    385
    He..he. Hold on. I'll give you the source code.

  6. #6
    Registered User
    Join Date
    Aug 2011
    Posts
    385
    Input:
    Code:
    Enter elements for acc
    1
    a
    15
    2
    b
    10
    
    Enter elements for trans
    1
    d
    15
    2
    w
    5
    Expected output
    Code:
    1 a 30.000000
    2 b 5.000000
    Actual output
    Code:
    1 a 30.000000
    2 b 10.000000

    Code:
    #include<stdio.h>
    
      
    int main(void)
    {
    	struct
    	{
    		int accno;
    		char transtype;
    		float amt;
    	}trans;
        
    	struct
    	{
    		int accno;
    		char name[30];
    		float bal;
    	}acc;
    	FILE *fa, *ft;
    	long pos1, pos2;
    
    	if((fa=fopen("acc.txt","w+"))==NULL)
    		puts("Unable to open");
    
    	if((ft=fopen("trans.txt","w+"))==NULL)
    		puts("Unable to open");
    
    	puts("Enter elements for acc");
    	while((scanf("%d %s %f",&acc.accno,acc.name,&acc.bal)) == 3)
    		fwrite(&acc,sizeof(acc),1,fa);
    
    	puts("Enter elements for trans");
    	while(scanf("%d %c %f",&trans.accno,&trans.transtype,&trans.amt)==3)
    		fwrite(&trans,sizeof(trans),1,ft);
    
    	fclose(fa);
    	fclose(ft);
    
    	if((fa=fopen("acc.txt","r+"))==NULL)
    		puts("Unable to open");
    
    	if((ft=fopen("trans.txt","r"))==NULL)
    		puts("Unable to open");
    
    	while(fread(&trans,sizeof(trans),1,ft) == 1)
    	{
    		rewind(fa);
    		pos2 = ftell(fa);
    		while(fread(&acc,sizeof(acc),1,fa) == 1)
    		{
    			if(acc.accno == trans.accno)
    			{
    				fseek(fa,pos2,0);
    				if(trans.transtype == 'd')
    					acc.bal+=trans.amt;
    				else
    					acc.bal-=trans.amt;
    				
    				fwrite(&acc,sizeof(acc),1,fa);
    			}
    			
    			pos2=ftell(fa);
    			fflush(fa);
    			/*fseek(fa,pos2,0);*/
    		}
    		
    	}
    
    	rewind(fa);
    	printf("\nOutput\n");
    	while(fread(&acc,sizeof(acc),1,fa)==1)
    		printf("%d %s %f\n",acc.accno,acc.name,acc.bal);
    
    	fclose(fa);
    	fclose(ft);
    }
    Run this under MSVC 2010, then under Pelles C, OR otherwise, run it under MSVC 2010 first with fseek commented out, and then with fseek uncommented.

  7. #7
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    IMHO, fwrite and fread should only be used on Binary files; not on Text files like you are doing.

    Tim S.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    The bug is in your code.

    Quote Originally Posted by C99 Clause 7.19.5.2 Paragraph 3
    If stream points to an output stream or an update stream in which the most recent operation was not input, the fflush function causes any unwritten data for that stream to be delivered to the host environment to be written to the file; otherwise, the behavior is undefined.
    Observe this loop carefully:
    Code:
    while (fread(&acc, sizeof(acc), 1, fa) == 1)
    {
        if (acc.accno == trans.accno)
        {
            fseek(fa, pos2, 0);
            if (trans.transtype == 'd')
                acc.bal += trans.amt;
            else
                acc.bal -= trans.amt;
    
            fwrite(&acc, sizeof(acc), 1, fa);
        }
    
        pos2 = ftell(fa);
        fflush(fa);
    }
    Now, fa is an update stream. Notice that there is a call to fwrite. This satisfies the requirement for "an update stream in which the most recent operation was not input". However, the call to fwrite happens if acc.accno == trans.accno. If not, the most recent operation on fa would be the call to fread, i.e., an input operation, leading to undefined behaviour when control reaches fflush(fa).

    Looking at what you commented out, perhaps you intended to write this instead:
    Code:
    while (fread(&acc, sizeof(acc), 1, fa) == 1)
    {
        if (acc.accno == trans.accno)
        {
            fseek(fa, pos2, 0);
            if (trans.transtype == 'd')
                acc.bal += trans.amt;
            else
                acc.bal -= trans.amt;
    
            fwrite(&acc, sizeof(acc), 1, fa);
            fflush(fa);
        }
    
        pos2 = ftell(fa);
        fseek(fa, pos2, 0);
    }
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Registered User
    Join Date
    Aug 2011
    Posts
    385
    Is it necessary that fread and fwrite be used only with binary files?

  10. #10
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by juice View Post
    Is it necessary that fread and fwrite be used only with binary files?
    You need to spend some time reading the details on these functions and perhaps studying a decent tutorial on C...

    Look in your compiler's library documentation, it should give you the full skinny on what each function does.
    (IIRC... you're using Pelles C... so this is simple, put your text cursor (the flashing bar) on one of he keyworkds and press F1 on your keyboard)

    Basically...
    Functions such as fprintf(), fscanf(), fputs(), fgets() work with human readable text. There is a translation from binary to text when writing then from text back to binary when reading...

    Functions such as fwrite() and fread() do no translations. They simply copy memory to a disk file or a disk file to memory. So the binary content of memory ends up in your disk file. You might be able to read some of it... but it's not text.


    Thing is, I've been watching you launch thread after thread about this EOF boggle you seem to have going on... No offense, but you really do need to do some reading up on this stuff. It's not difficult... unless you don't know it.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Got Error in Pointer increment. Help !!!
    By mysql2779 in forum C Programming
    Replies: 9
    Last Post: 03-19-2011, 02:10 AM
  2. Increment a pointer variable
    By skiabox in forum C Programming
    Replies: 5
    Last Post: 11-17-2010, 11:24 AM
  3. txt file from ofstream. Increment the files name?
    By Swerve in forum C++ Programming
    Replies: 5
    Last Post: 10-14-2008, 12:25 PM
  4. pointer increment error
    By WDT in forum C++ Programming
    Replies: 7
    Last Post: 12-09-2007, 08:01 AM
  5. Increment the address stored in a pointer???
    By patricio2626 in forum C++ Programming
    Replies: 9
    Last Post: 04-04-2007, 06:36 PM