Thread: Multiple inputs separated by EOF

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

    Multiple inputs separated by EOF

    Why does the program below terminate as soon as the input for first file (acc.txt) is entered. Why doesn't the control enter the second while loop

    Code:
    #include<stdio.h>
    
      
    int main(void)
    {
    	struct
    	{
    		int accno;
    		char tt;
    		float amt;
    	}x;
        
    	struct
    	{
    		int accno;
    		char name[30];
    		float bal;
    	}y;
        
        FILE *fa,*ft;
      
        if((fa=fopen("acc.txt","wb+"))==NULL)
    		printf("Unable to open");
        if((ft=fopen("trans.txt","wb+"))==NULL)
    		printf("Unable to open");
        
        printf("Enter elements for acc.txt (accno, name, bal)\n");
    
        while(scanf("%d %s %f",&y.accno,y.name,&y.bal)!=EOF)
    	{
    		fflush(stdin);
    		fwrite(&y,sizeof(y),1,fa);
    		fflush(stdin);
    	}
    
    	fflush(stdin);
    
    	printf("\nEnter contents for trans.txt(accno, tt, amt)\n");
    	while(scanf("%d %s %f",&x.accno,&x.tt,&x.amt)!=EOF)
    	{
    		fwrite(&x,sizeof(x),1,ft);
    		fflush(stdin);
    	}
    }

  2. #2
    Registered User
    Join Date
    Aug 2011
    Posts
    385
    Can anyone please tell me wats wrong..

  3. #3
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    How are you trying to generate the EOF with your scanf()? You should be testing that scanf() returned the number of items requested. EOF will only be generated on an error for the first item. Also fflush() is only defined in the standard to work on output streams, not input streams.

    Jim

  4. #4
    Registered User
    Join Date
    Aug 2011
    Posts
    385
    Help...

  5. #5
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    Did you try reading the documentation for scanf()? Pay attention to the return value.

    Jim

  6. #6
    Registered User
    Join Date
    Aug 2011
    Posts
    385
    scanf returns an EOF when it encounters the end of file marker (ctrl-Z for windows), try it on ur machine.

  7. #7
    Registered User
    Join Date
    Dec 2011
    Posts
    795
    Quote Originally Posted by juice View Post
    Code:
            fflush(stdin);
    Don't do this. FAQ > Why fflush(stdin) is wrong - Cprogramming.com

    Quote Originally Posted by juice View Post
    Code:
            fwrite(&y,sizeof(y),1,fa);
    You're letting the compiler pack the struct however it wants to. This almost guarantees that it will be unreadable to a user, and possibly will be non-portable across systems.

    Also, don't bump three times.

  8. #8
    Registered User
    Join Date
    Aug 2011
    Posts
    385
    Quote Originally Posted by memcpy View Post
    Don't do this. FAQ > Why fflush(stdin) is wrong - Cprogramming.com



    You're letting the compiler pack the struct however it wants to. This almost guarantees that it will be unreadable to a user, and possibly will be non-portable across systems.

    Also, don't bump three times.
    ...didn't get it??

  9. #9
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    scanf returns an EOF when it encounters the end of file marker (ctrl-Z for windows).
    No it does not. It returns the number of items read. There is also no end of file when using the console. Control-Z has never been a reliable way of testing for end of file with MSDOS or any Windows operating system. This method was used for the CPM operating system, which predates MSDOS, and only the earliest DOS programs supported it. In DOS/Windows the operating system, not something in the file, reports end of file.

    Jim

  10. #10
    Registered User
    Join Date
    Aug 2011
    Posts
    385
    Code:
    #include<stdio.h>
    int main()
    {
    int i;
    printf("%d",scanf("%d",&i));
    }
    Compile this on ur machine, provide ctrl-Z as input and then check the output..

  11. #11
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    Enter the following code:
    Code:
    #include<stdio.h>
    int main()
    {
       int i;
       int c;
       int d;
       i = scanf("%d%d",&c, &d );
       printf("%d",i);
    }
    Run this program. For the first number enter a 2 (then press the enter key ) then your ctrl-Z for the second item, what does the program print? It should print "1". The reason you are getting -1 is because scanf() failed to get any information.

    Edit: By the way your program produces "^Z" on my machine.


    Jim

  12. #12
    Registered User andrew89's Avatar
    Join Date
    Dec 2011
    Location
    Indiana, United States
    Posts
    80
    Seriously... I'm not easily annoyed, but this is ridiculous. You're ignoring everything everyone is telling you.

    ctrl+z may or may not make an EOF character, that's not the point.

    The point is, scanf returns the number of items read, not EOF.

    This is like the story of the guy who went out with a million different girls once and never again and said, "I don't know what's wrong with them," after a million, you'd think you would realize the problem is with you. I had to clean that up to make it PG-13 so if it doesn't make much sense forgive me.

    You've got ~10 people in ~30 threads telling you the same thing over and over again. Eventually you're going to annoy them to the point where they stop caring.

    EDIT: EOF byte
    Windows: CTRL+Z
    *nix: CTRL+D

    In the C Standard Library, the character reading functions such as getchar return a value equal to the symbolic value (macro) EOF to indicate that an end-of-file condition has occurred. The actual value of EOF is system-dependent (but is commonly -1, such as in glibc) and is unequal to any valid character code. Block-reading functions return the number of bytes read, and if this is fewer than asked for, then the end of file was reached.
    Last edited by andrew89; 12-27-2011 at 12:33 PM.
    If, for some reason, I don't make any sense at all, it's highly likely that I've been up all night on some strange bender that isn't normal. I likely unarmed and far from dangerous. While I haven't been known to physically harm anyone or anything else, there have been unsubstantiated reports that I have driven others into both a hazy stupor as well as a blinding rage. Otherwise, I hope I helped.

  13. #13
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,663
    > Why doesn't the control enter the second while loop
    Because the EOF you signalled to end the first loop hasn't gone away by the time you hit the second loop - so it will exit immediately because the stdin stream is still in the end of file state.

    Perhaps something like
    clearerr(stdin);

    Or better, separate input from conversion, and get rid of all those horrid fflush() calls.
    Code:
    #include<stdio.h>
    
    
    int main(void)
    {
        struct
        {
            int accno;
            char tt;    //!! you can't store a string here
            float amt;
        }x;
    
        struct
        {
            int accno;
            char name[30];
            float bal;
        }y;
        char buff[BUFSIZ];
        FILE *fa,*ft;
    
        if((fa=fopen("acc.txt","wb+"))==NULL)
            printf("Unable to open");
        if((ft=fopen("trans.txt","wb+"))==NULL)
            printf("Unable to open");
    
        printf("Enter elements for acc.txt (accno, name, bal)\n");
        while ( fgets( buff, sizeof(buff), stdin) != NULL ) {
          if ( sscanf(buff,"%d %s %f",&y.accno,y.name,&y.bal)==3) {
            fwrite(&y,sizeof(y),1,fa);
          } else {
            break;
          }
        }
    
        printf("\nEnter contents for trans.txt(accno, tt, amt)\n");
        while ( fgets( buff, sizeof(buff), stdin) != NULL ) {
          if ( sscanf(buff,"%d %s %f",&x.accno,&x.tt,&x.amt) == 3 ) {
            fwrite(&x,sizeof(x),1,ft);
          } else {
          }
        }
    
        fclose(fa);
        fclose(ft);
    
        return 0;
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  14. #14
    Registered User
    Join Date
    Aug 2011
    Posts
    385
    Quote Originally Posted by andrew89 View Post
    Seriously... I'm not easily annoyed, but this is ridiculous. You're ignoring everything everyone is telling you.

    ctrl+z may or may not make an EOF character, that's not the point.

    The point is, scanf returns the number of items read, not EOF.

    This is like the story of the guy who went out with a million different girls once and never again and said, "I don't know what's wrong with them," after a million, you'd think you would realize the problem is with you. I had to clean that up to make it PG-13 so if it doesn't make much sense forgive me.

    You've got ~10 people in ~30 threads telling you the same thing over and over again. Eventually you're going to annoy them to the point where they stop caring.

    EDIT: EOF byte
    Windows: CTRL+Z
    *nix: CTRL+D

    In the C Standard Library, the character reading functions such as getchar return a value equal to the symbolic value (macro) EOF to indicate that an end-of-file condition has occurred. The actual value of EOF is system-dependent (but is commonly -1, such as in glibc) and is unequal to any valid character code. Block-reading functions return the number of bytes read, and if this is fewer than asked for, then the end of file was reached.
    I could't understand, were you trying to tell me that scanf should not be used to return EOF? or were you trying to tell jim that scanf could also return EOF and not just the number of characters read? Cause if you were talking to jim then I want to ask why the following code teriminates after going through the second while loop only once??

    Code:
    #include<stdio.h>
    
    int main()
    {
    	FILE *ft;
    	struct
    	{
    		int i;
    		char c;
    		float d;
    	}a,b;
    
    
    	ft=fopen("something.txt","wb+");
    
    	printf("Enter some random contents (int followed by char followed by float)\n");
    	
    	while((scanf("%d %c %f",&a.i,&a.c,&a.d))!=EOF)
    		fprintf(ft,"%d %c %f",a.i,a.c,a.d);
    
    	printf("\n");
    	
    	rewind(ft);
    
    	while(fscanf(ft,"%d %c %f",&b.i,&b.c,&b.d)!=0)
    		printf("%d %c %f\n",b.i,b.c,b.d);
    		
    	fclose(ft);
    }
    Last edited by juice; 12-27-2011 at 10:10 PM.

  15. #15
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by juice
    why the following code teriminates after going through the second while loop only once?
    When asking such a question in which the program accepts external input, you should also state what was the given input, 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

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. scanning multiple inputs
    By casey123 in forum C Programming
    Replies: 2
    Last Post: 10-17-2011, 01:47 AM
  2. Multiple inputs on one line.
    By rekluse in forum C Programming
    Replies: 4
    Last Post: 04-21-2008, 06:53 PM
  3. multiple inputs of multiple types
    By frontz in forum C Programming
    Replies: 8
    Last Post: 01-19-2004, 02:57 PM
  4. Multiple inputs with cin
    By DJPG5 in forum C++ Programming
    Replies: 2
    Last Post: 02-16-2003, 04:10 PM
  5. Getting multiple inputs using cin
    By edk in forum C++ Programming
    Replies: 2
    Last Post: 09-13-2001, 02:34 PM