sscanf returns nothing

Discussion in 'Mac Programming' started by MrFusion, Feb 3, 2011.

  1. MrFusion macrumors 6502a

    Joined:
    Jun 8, 2005
    Location:
    West-Europe
    #1
    I found this code fragment with google, but the output is "Input [__]".
    input_buf contains "test\n" according to the debugger, which is what I entered.
    Any idea why this isn't working?

    My goal is to ask the user a question (via the command line) and evaluate the response.
    Thanks

    Code:
    	char input_buf[64] = {0};
    	char data[64] = {0};
    	
    	printf("Enter something: ");
    	while( fgets(input_buf, sizeof(input_buf), stdin) == NULL )
    	{
    		/* parse the input entered */
    		sscanf(input_buf, "%s", data);
    	}
    	
    	printf("Input [_%s_]\n", data);	
    
     
  2. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #2
    Where exactly did you find that code? I want to know what URL to avoid.

    Look carefully at the red-hilited piece. Under what circumstances does fgets() return NULL? What does it return under other circumstances? Which of those do you want to loop under?
     
  3. Bill McEnaney macrumors 6502

    Joined:
    Apr 29, 2010
    #3
    It's as though the program is telling the computer to keep parsing when there's nothing to parse. If the computer reads a nonempty string, it won't execute the sscanf.

    Why would anyone put the integer zero, not the numeral 0, into a string? To put the null character into the array, I need to type '\0', not a zero.
     
  4. Cromulent macrumors 603

    Cromulent

    Joined:
    Oct 2, 2006
    Location:
    The Land of Hope and Glory
    #4
    That just initialises the array to all 0 so that you know it doesn't contain garbage. Unless of course I have misunderstood which bit you are talking about :p, which is quite likely at the moment.
     
  5. balamw, Feb 3, 2011
    Last edited: Feb 3, 2011

    balamw Moderator

    balamw

    Staff Member

    Joined:
    Aug 16, 2005
    Location:
    New England
    #5
    The loop doesn't make sense to me even if you do fix it. Isn't this the kind of construct you might use to read a multi-line file into a buffer since it will exit on eof (once "fixed")? You want to exit the loop once you've got good input, right? Not keep going replacing each line until you error out.

    Obviously I'm missing something.

    EDIT: (Also the use of fgets just to turn around and use sscanf to copy it to another array just seems wrong. I too would like to know where this came from to avoid going there).

    B
     
  6. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #6
    The numeral 0 is this character constant: '0'. Its integer value is 0x30, which is decidedly different from integer zero.

    The character constant '\0' has an integer value of 0.

    C is not strictly typed when it comes to characters. For all intents and purposes, the char type is equivalent to a small integer type. It can perform all operations exactly as if it were a small integer. It can even be signed, despite the fact that no charset actually has negative codes.
     
  7. MrFusion, Feb 3, 2011
    Last edited by a moderator: Feb 8, 2011

    MrFusion thread starter macrumors 6502a

    Joined:
    Jun 8, 2005
    Location:
    West-Europe
    #7
    I found it here.

    I have no idea.

    I first tried fscan, but that didn't wait at all for any user input.

    The consensus is that this is crappy code. Fine by me. But what would then be the recommended way to ask the user for input on the command line? I know about argv[], but I mean during runtime. I tried google, but didn't find a decent example.
     
  8. balamw, Feb 3, 2011
    Last edited: Feb 3, 2011

    balamw Moderator

    balamw

    Staff Member

    Joined:
    Aug 16, 2005
    Location:
    New England
    #8
    http://www.daniweb.com/forums/thread93390.html has some discussion about the differences between scanf and fgets. (First Google hit).

    Code:
    char data[64];
     
    if ( fgets ( data, sizeof(data), stdin ) != NULL )
      printf("Input [_%s_]\n", data);
    B
     
  9. subsonix macrumors 68040

    Joined:
    Feb 2, 2008
    #9
    As you can see, fgets returns NULL only if fgets fails to get any characters. In your case, fgets capture your string from stdin and returns the pointer, and thus the while loop is never executed.
     
  10. gnasher729, Feb 3, 2011
    Last edited: Feb 3, 2011

    gnasher729 macrumors P6

    gnasher729

    Joined:
    Nov 25, 2005
    #10
    Google for N1256.pdf. Download the document that you find. Search for the function that you have no idea about and read what it says. You have no chance of ever writing code that will work unless you know what you are doing, and reading the documentation is the way to learn this.


    Wouldn't it be better to ask: How can I find out why this isn't working? I'd change the code as follows:

    Code:
    	char input_buf[64] = {0};
    	char data[64] = {0};
    	
    	printf("Enter something: ");
    	for(;;) {
                char* fgets_result = fgets(input_buf, sizeof(input_buf), stdin);
                if (fgets_result != NULL )
                    break;
    	    /* parse the input entered */
    	    sscanf(input_buf, "%s", data);
    	}
    	
    	printf("Input [_%s_]\n", data);	
    
    Now set a few breakpoints, start with debugger, and see what happens. Isn't that a lot easier than asking people for help?
     
  11. balamw Moderator

    balamw

    Staff Member

    Joined:
    Aug 16, 2005
    Location:
    New England
    #11
    Try checking the man page on your system as subsonix suggests before going to the full on spec.
    Code:
    man 3 fgets
    B
     
  12. MrFusion thread starter macrumors 6502a

    Joined:
    Jun 8, 2005
    Location:
    West-Europe
    #12
    Great advice! If you know what you have to look for or if you are familiar with these low level c routines.
    Being rushed to fix this problem also didn't help.

    Anyway, this works:
    Code:
    	char input_buf[64] = {0};
    	char data[64] = {0};
    	char data2[64] = {0};
    	char stop[] = "stop";
    	
    	printf("Enter something: ");
    	while (TRUE)
    	{
    		char* fgets_result = fgets(input_buf, sizeof(input_buf), stdin); //retrieve data from stdin (= command line). fgets_result points to input_buf
    		sscanf(input_buf, "%s %s", data, data2);	//parses inputbuf according to middle argument and dumps results in the char arrays. View this as a reversed printf.
    		if (strncmp(data2,stop,sizeof(stop)) == 0) //only the first x=sizeof(stop) characters are compared. Also works if data2 is longer, even though the first x characters are a match.
    			break;
    		printf("Intermediate input [_%s_] [_%s_] \n", data, data2);
    		printf("Enter something else: ");
    	}
    	printf("Input [_%s_] [_%s_] \n", data, data2);
    
    Thanks for pointing out the direction.
     
  13. Bill McEnaney, Feb 4, 2011
    Last edited: Feb 4, 2011

    Bill McEnaney macrumors 6502

    Joined:
    Apr 29, 2010
    #13
    I know that the character zero isn't the integer zero.


    That's why I can add a character to an integer. If I wanted to ensure that a string variable's value wasn't garbage, I would have initialized that variable with a blank, which you can also treat as an integer. Better yet(?), if I wanted its value to be the null string, I would have typed two consecutive double quotation marks with nothing between them.
     

Share This Page