Click to See Complete Forum and Search --> : scanf misbehaving...


YourSurrogateGod
October 6th, 2005, 11:16 PM
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...
$ ./main
Input something - > wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
wwwwwwwwwwwwwwwwwwww
Input something - > w

Kheun
October 7th, 2005, 01:11 AM
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().

YourSurrogateGod
October 7th, 2005, 10:21 AM
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?

YourSurrogateGod
October 7th, 2005, 10:26 AM
Ok, I just put fflush(stdin); after scanf in grab_string();, no go, same problem persists.

YourSurrogateGod
October 7th, 2005, 12:37 PM
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.

Kheun
October 9th, 2005, 07:57 PM
Sorry for the late reply. I haven't been accessing the internet over the weekend.

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.



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;
}

YourSurrogateGod
November 8th, 2005, 11:31 PM
These are the files that I have and this is the output that I'm getting:
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.

Kheun
November 14th, 2005, 02:33 AM
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.


// 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.

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