Thread: fgets problem

  1. #1
    Registered User
    Join Date
    Oct 2006
    Posts
    17

    fgets problem

    I have the following code:

    Code:
    #include <stdio.h>
    
    #define N 2
    
    int main()
    {
    
    
    	int A[N][N];
    	int i,j;
    	char text[100];
    
    	
    	
    	printf("input\n"); 
    	for (i=0;i<N;i++)
    		for (j=0;j<N;j++)
    		{
    			printf("element %d,%d ",i,j);
    			scanf("%d",&A[i][j]);
    		}
    	printf("Input text:\n");
    	fgets(text,40,stdin);
    	printf("%s",text);
    return 0;
    }
    The output is:
    $./a.out
    input
    element 0,0 1
    element 0,1 2
    element 1,0 3
    element 1,1 4
    Input text:

    $


    The problem is that it terminates before it reads my string.
    What should I change in order to make it work?

  2. #2
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    scanf and fgets don't mix very well.
    scanf leaves the terminating '\n' in the input buffer. the following fgets finds the '\n' and returns an empty string.
    Kurt

  3. #3
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    after you enter the number '\n' symbol is left in the input stream, next scanf ignores it, but fgets does not.

    So it reads that left symbol in to the text array and then - prints it
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  4. #4
    Registered User
    Join Date
    Oct 2006
    Posts
    17
    Yes, but what's the solution to this problem?
    I need to use scanf and fgets.
    Is there a way to remove the terminating '\n' from the input buffer?

    Which functions could I have used alternatively?

  5. #5
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    One solution could be to add another fgets statement or empty the buffer some other way.
    Kurt

  6. #6
    Registered User
    Join Date
    Oct 2006
    Posts
    17
    ZuK I already tried the additional fgets, but it appears weird that way.

    Anyone know how to empty the buffer in another way?

  7. #7
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Code:
     int ch;
      do
        ch = fgetc ( stdin ); 
      while ( ch != EOF && ch != '\n' );
    Would help.
    Kurt

  8. #8
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Anyone know how to empty the buffer in another way?
    you can remove scanf and use pair
    fgets/sscanf or fgets/strtol

    in this case there will be no mix of fgets/scanf
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  9. #9
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    Code:
    void clear_buffer()
    {
        int ch;
        
        while((ch = getchar()) != EOF && ch != '\n');
    }
    ssharish2005

  10. #10
    Registered User
    Join Date
    Nov 2006
    Posts
    2
    use _fpurge or _fflush to remove \n from the buffer

  11. #11
    Registered User
    Join Date
    Nov 2006
    Posts
    7
    i suggest you

    replace this

    scanf("%d",&A[i][j]);
    =>
    scanf("%d%c",&A[i][j]);

  12. #12
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    scanf("%d%c",&A[i][j]); - you ask to read 2 values providing space only for one... the character will be written somewhere on the stack...
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  13. #13
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > use _fpurge or _fflush to remove \n from the buffer
    Please don't suggest non-standard functions which don't solve the problem for everyone.

    > scanf("%d%c",&A[i][j]);
    Which fails just as miserably if the user types a space after the last digit entered.

    > I need to use scanf and fgets.
    You mean something else like scanf is OK if it works in a similar manner?
    Or is this an exercise in understanding that scanf() and fgets() don't play together?

    For example, what about this for you loop
    Code:
    printf("element %d,%d ",i,j);
    fflush( stdout );
    if ( fgets( text, sizeof text, stdin ) != NULL ) {
      if ( sscanf( text, "%d",&A[i][j]) == 1 ) {
      } else {
        // error message
      }
    }
    No scanf() to muck up the input stream, so the final fgets() will do the right thing unless the user is deliberately out to try and buffer overflow attack your code (in which case it's their problem).

    > fgets(text,40,stdin);
    It's exceedingly unwise to guess at the buffer size, even if you happen to guess smaller.
    fgets(text, sizeof text,stdin);
    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
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Quote Originally Posted by vart
    scanf("%d%c",&A[i][j]); - you ask to read 2 values providing space only for one... the character will be written somewhere on the stack...
    Assuming you don't mind it failing miserably as Salem mentioned, you can get scanf() to skip format specifiers with a * (in printf a * does something different). %*X
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  15. #15
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Learning the whole of C (except for scanf), and learning scanf() takes about the same amount of time.

    All those ways to use it, and all those ways to louse it up as well.
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem with fgets....
    By Huskar in forum C Programming
    Replies: 5
    Last Post: 03-29-2009, 10:13 AM
  2. Words and lines count problem
    By emo in forum C Programming
    Replies: 1
    Last Post: 07-12-2005, 03:36 PM
  3. problem with fgets
    By learninC in forum C Programming
    Replies: 3
    Last Post: 05-19-2005, 08:10 AM
  4. print problem while using fgets()
    By learninC in forum C Programming
    Replies: 12
    Last Post: 05-15-2005, 09:29 PM
  5. binary tree problem - help needed
    By sanju in forum C Programming
    Replies: 4
    Last Post: 10-16-2002, 05:18 AM