CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8
  1. #1
    Join Date
    Apr 2004
    Location
    In the back seat of New Horizons.
    Posts
    1,238

    scanf misbehaving...

    I'm not sure if I posted this before, sorry if I did. I'm using gcc. The files are attached.

    Pretty much whenever I input a really long string (over 20 characters) in the first method grab_string, the second time around a string is automatically inputted whenever I call grab_string_ml. Why is this happening and how can I fix it?

    Here's the console info that I have...
    Code:
    $ ./main
    Input something - > wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
    wwwwwwwwwwwwwwwwwwww
    Input something - > w
    Attached Files Attached Files
    Here are the rules, you must obey them or the gender bender will get you.

    And if you ever think of posting without code-tags, the evil monkey will come after you.

  2. #2
    Join Date
    Oct 2002
    Location
    Singapore
    Posts
    3,128

    Re: scanf misbehaving...

    grab_string_ml() captures the extra 'w' from the buffer in stdin. You can use fflush() to flush the extra input after calling scanf() in grab_string().
    quoted from C++ Coding Standards:

    KISS (Keep It Simple Software):
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.

    Avoid magic number:
    Programming isn't magic, so don't incant it.

  3. #3
    Join Date
    Apr 2004
    Location
    In the back seat of New Horizons.
    Posts
    1,238

    Re: scanf misbehaving...

    Quote Originally Posted by Kheun
    grab_string_ml() captures the extra 'w' from the buffer in stdin. You can use fflush() to flush the extra input after calling scanf() in grab_string().
    But I called fflush(stdin); after I called scanf in grab_string_ml(), wouldn't that be enough?
    Here are the rules, you must obey them or the gender bender will get you.

    And if you ever think of posting without code-tags, the evil monkey will come after you.

  4. #4
    Join Date
    Apr 2004
    Location
    In the back seat of New Horizons.
    Posts
    1,238

    Re: scanf misbehaving...

    Ok, I just put fflush(stdin); after scanf in grab_string();, no go, same problem persists.
    Here are the rules, you must obey them or the gender bender will get you.

    And if you ever think of posting without code-tags, the evil monkey will come after you.

  5. #5
    Join Date
    Apr 2004
    Location
    In the back seat of New Horizons.
    Posts
    1,238

    Re: scanf misbehaving...

    Ok, I tried fgets method, but that still doesn't do what I want (same problem.) I know I had this problem before (and yes I searched the forums before and no I didn't find the answer) but I don't remember how I solved it.
    Here are the rules, you must obey them or the gender bender will get you.

    And if you ever think of posting without code-tags, the evil monkey will come after you.

  6. #6
    Join Date
    Oct 2002
    Location
    Singapore
    Posts
    3,128

    Re: scanf misbehaving...

    Sorry for the late reply. I haven't been accessing the internet over the weekend.

    Quote Originally Posted by YourSurrogateGod
    Ok, I just put fflush(stdin); after scanf in grab_string();, no go, same problem persists.

    That's strange. It works for me. See the code below.

    BTW, I have made changes to your code as it is giving me warnings. The compiler requires casting the void pointer after calloc. In addition, there is an execuation path in grab_string_ml where it is not returning any value.

    Code:
    char * grab_string_ml(int length)
    {
     if(length > 0)
     {
      // create a dynamically allocated piece of memory that will store a string of a maximum of length + 1 characters long.
      char * input = (char*)calloc(length + 1, CHAR_BIT);
      // this will hold the middle portion inputted array.
      char middle[5];
    
      // create the beginning of the string that will be used in oder to input a value into the character array.
      char * beginning = "%";
      // create the ending of the string that will be used in order to input a value into the character array.
      char * ending = "s";
      // create a pointer to a character array that will store the final results.
      char * target = NULL;
    
      // convert an integer into a character array.
      sprintf(middle, "%d", length);
    
      // allocate the necessary space for the target.
      target = (char*)calloc(strlen(beginning) + strlen(middle) + strlen(ending) + 1, CHAR_BIT);
    
      // copy the characters from the beginning into the target.
      strncat(target, beginning, strlen(beginning));
      strncat(target, middle, strlen(middle));
      strncat(target, ending, strlen(ending));
    
      // have the user input something.
      scanf(target, input);
      // flush the input.
      fflush(stdin);
    
      // free the allocated memory.
      free(target);
    
      // return the desired value.
      return input;
     }
     else
     {
      fprintf(stderr, "The inputted value is less than one.\n");
     }
    
     return 0;    // Added to return a value indicating error.
    }
    
    char * grab_string()
    {
     // create a dynamically allocated piece of memory that will store a string of a maximum of 21 characters long.
     char * input = (char*)calloc(21, CHAR_BIT);
    
     // grabe the value from the user.
     scanf("%20s", input);
     fflush(stdin);    // Flushing the input buffer.
    
     // return the inputted string.
     return input;
    }
    
    
    
    
    
    int main()
    {
     // ask the user input something.
     printf("Input something - > ");
     char * value1 = grab_string();
     // output the inputted string.
     printf("%s\n", value1);
     // ask the user input something.
     printf("Input something - > ");
     char * value2 = grab_string_ml(1);
     // output the inputted string.
     printf("%s\n", value2);
    
     // free the memory.
     free(value1);
     free(value2);
    
     return 0;
    }
    quoted from C++ Coding Standards:

    KISS (Keep It Simple Software):
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.

    Avoid magic number:
    Programming isn't magic, so don't incant it.

  7. #7
    Join Date
    Apr 2004
    Location
    In the back seat of New Horizons.
    Posts
    1,238

    Re: scanf misbehaving...

    These are the files that I have and this is the output that I'm getting:
    Code:
    Using method grab_string_ml.
     Please input a value - > wwwwwwwwwwwww
     Please input a second value - > char1 = wwwww
    char2 = www
    
    Using method grab_string.
     Please input a value - >  Please input a second value - > wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
    char3 = wwwww
    char4 = wwwwwwwwwwwwwwwwwwww
    I give up.
    Attached Files Attached Files
    Here are the rules, you must obey them or the gender bender will get you.

    And if you ever think of posting without code-tags, the evil monkey will come after you.

  8. #8
    Join Date
    Oct 2002
    Location
    Singapore
    Posts
    3,128

    Re: scanf misbehaving...

    I am very sorry that I couldn't reply earlier as I am quite busy with my work nowadays.

    I have made some changes to your code in order to compile and handles memory leak. Everything else works fine on VC7.

    Code:
    // In custom_input.c
    int grab_int_ml(int length)
    {
     if(length > 0)
     {
      // create an array of characters that will be used to store an input as a 
      //  string, from which the integer will be taken out of.
      char input[255];  // Must be a constant value.
    
      // this will hold the middle portion inputted array.
      char middle[5];
    
      // create the beginning of the string that will be used in oder to input a 
      //  value into the character array.
      char * beginning = "%";
      // create the ending of the string that will be used in order to input a 
      //  value into the character array.
      char * ending = "s";
      // create a pointer to a character array that will store the final results.
      char * target;
    
    
      // convert an integer into a character array.
      sprintf(middle, "%d", length);
    
      // allocate the necessary space for the target.
      target = calloc(strlen(beginning) + strlen(middle) + strlen(ending) + 1, 
       CHAR_BIT);
    
      // copy the characters from the beginning into the target.
      strncat(target, beginning, strlen(beginning));
      strncat(target, middle, strlen(middle));
      strncat(target, ending, strlen(ending));
    
      // have the user input something.
      scanf(target, input);
    
      // free allocated resources.
      free(target);
    
      // convert the string to an integer and return it.
      return atoi(input);
     }
     else
     {
      fprintf(stderr, "The inputted value is less than one.\n");
     }
    
     return 0;
    }
    
    
    // In main.c
    int main()
    {
      // Only in C, declaration must comes first before the rest of the function.
      char *char1, *char2, *char3, *char4; 
    
     /*printf("Using method grab_int_ml.\n");
     printf(" Please input a value - > ");
     int val1 = grab_int_ml(2);
     printf(" Please input a second value - > ");
     int val2 = grab_int_ml(3);
     printf("val1 = %d\nval2 = %d\n\n", val1, val2);
     printf("Using method grab_int.\n");
     printf(" Please input a value - > ");
     int val3 = grab_int();
     printf(" Please input a second value - > ");
     int val4 = grab_int();
     printf("val3 = %d\nval4 = %d\n\n", val3, val4);*/
    
     printf("Using method grab_string_ml.\n");
     printf(" Please input a value - > ");
     //char * char1 = grab_string_ml(5);
     char1 = grab_string_ml(5);
     printf(" Please input a second value - > ");
     //char * char2 = grab_string_ml(3);
     char2 = grab_string_ml(3);
     printf("char1 = %s\nchar2 = %s\n\n", char1, char2);
     //Releasing memory.
     free(char1);
     free(char2);
    
     printf("Using method grab_string.\n");
     printf(" Please input a value - > ");
     //char * char3 = grab_string();
     char3 = grab_string();
     printf(" Please input a second value - > ");
     //char * char4 = grab_string();
     char4 = grab_string();
     printf("char3 = %s\nchar4 = %s\n\n", char3, char4);
     //Releasing memory.
     free(char3);
     free(char4);
    
     return 0;
    }

    Here's my output.
    Code:
    Using method grab_string_ml.
     Please input a value - > wwwwwwwwwwwwwwwwwwwwww
     Please input a second value - > ssssssssssssssssssssssss
    char1 = wwwww
    char2 = sss
    
    Using method grab_string.
     Please input a value - > dddddddddddddddddddddddddddddddddddddddddddd
     Please input a second value - > eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
    char3 = dddddddddddddddddddd
    char4 = eeeeeeeeeeeeeeeeeeee
    quoted from C++ Coding Standards:

    KISS (Keep It Simple Software):
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.

    Avoid magic number:
    Programming isn't magic, so don't incant it.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured