-
Strange scanf behavior
Here is a small program i have written and I cannot figure out why my keyboard buffer is not behaving bad like it shouldwith this flawed code.
also keep in mind this is not all of the code the part with the menu printf stuff has been removed. sorry had to retype the whole program seeing im not at home. :p
this code only tested in linux by the way.
Code:
#include<stdlib.h>
#include<stdio.h>
int menu(void);
int main()
{
int vaid = 0;
printf("Below is the return from menu.\n%d\n",menu());
scanf("%d",&vaid);
printf("%d\n",vaid);
}
int menu (void)
{
int option = 0;
int errchk;
char *data;
data = (char *) malloc (4); // shouldent need much more then 4
do {
// in here is some code to display a menu yada yada
scanf("%s",data); // get only one option
errchk = sscanf(data,"%d",&option);
if (errchk != 1) // there should only be one option found
{
return 4; // not one of the options so it makes the main loop loop again.
}
}
while (option == 0 || option > 3);
free (data);
return option;
}
when this is compiled and run here is the output
me@Nightshade$ ./testmen
Please enter a selection
1: To get APM info
2: To get process info
3: To exit
:>tttttttttttttttttttttttttttttttttttttttttttttttt ttttttttttttttttttttttttttttttttt <-- this is what i enterd
below is the return value from menu
4
<-- then it waits for the user to enter something again if the buffer had data still it should auto pop this area
but it doesent?
does free() somehow dump the buffers too ?
-
Assuming there really isn't a space in that, because the forum will insert one in long lines, there's nothing "wrong" with what's happening. By that I mean, your "%s" call with scanf reads until it hits whitespace. You don't have any white space, so it reads until it hits enter. There's nothing typed after that, so it sits at your scanf call outside of the function, after it has returned.
That aside, your code is horrible. Since you mention "this flawed code", I'll assume that's by design.
Quzah.
-
yes but shouldent it messup because the memory allocated for data is too small to hold the entire string of data.
its called a buffer overrun because the data in the buffer stdin is longer then the data variable that im tying to shove it into so it should overrun into the next input call witch i do at the bottem but it doesent the stream stdin seams to be dumped after menu has compleated.
is this a part of scanf's normal operation ?
-
also this used to be a function to a main program in another source file so this may be why it looks bad and the comments here make little sense.
-
I'm familliar with a buffer overrun. A buffer overrun simply means you're running past the end of some spot in memory. IE: You set aside 4 bytes, and you read more. That doesn't mean it has anything to do with how you read input however. It means, wherever in memory that four bytes is stored, you've trounced past the end of it into wherever else is there. This may or may not have an effect on other input calls.
In this case it doesn't, and shouldn't. However, since you're trashing your memory, pretty much anything can happen. It doesn't mean it will. It's pretty much undefined. There's no reason to think it should intrude on another input call. Why should it? That's just reading something else. It's where you're storing it that's the problem. Not where you're reading it from.
Quzah.
-
Ahh i see. So even if you use malloc to only allocate 4 bytes and you shove more data into the pointer to the 4 bytes of memory then scanf will read the entire string. I thought that scanf would only read 4 bytes and leave the rest in the input buffer. and when another scanf was done would use what was left in the buffer as input.
I do apologize I have little info on exactly how scanf works because of being spoiled with getline ( a gnu only input methood)
-
Nope. It'll just read whatever. Like gets. It doesn't have any boundry checking. Now you can sort of make scanf only read a number of characters. But unless you specify a width specifier, it'll just (with %s) read until it hits whitespace.
Quzah.
-
You shouldn't cast malloc, see the FAQ on why. int main() should return a value, like 0.