How to handle unknow size user input in C
Here are two examples to handle user input in C.
1. scanf
This method is easy get attack by buffer overflow, try input some characters which are more than what you declare to experience about what is buffer overflow.
#include
#include
int main()
{
char bStr[80];
printf("\nEnter a very very very long String value:");
scanf("%s", bStr);
printf("\nLong String value:%s \n\n",bStr);
return 0;
}
2. fgets
This method can protect buffer overflow by limit the character user input.
#include
#include
int main()
{
char bStr[80];
printf("\nEnter a very very very long String value:");
fgets ( bStr, 80, stdin );
printf("\nLong String value:%s \n\n",bStr);
return 0;
}
However, above two methods only can handle normal user input, how about i want to handle user input with 1000 or even more characters? Yes, we can declare like “char bStr[1000]
” or even more larger size, but this is not dynamic and flexible enough.
Solution
To fix it, uses realloc()
to increase memory size dynamically. First let see what above scanf()
buffer overflow look like, just input more than what you declare and see the result below.
Below example using dynamic memory allocation(realloc) in C to handle user input in unknown size.
#include
#include
int main()
{
unsigned int len_max = 128;
unsigned int current_size = 0;
char *pStr = malloc(len_max);
current_size = len_max;
printf("\nEnter a very very very long String value:");
if(pStr != NULL)
{
int c = EOF;
unsigned int i =0;
//accept user input until hit enter or end of file
while (( c = getchar() ) != '\n' && c != EOF)
{
pStr[i++]=(char)c;
//if i reached maximize size then realloc size
if(i == current_size)
{
current_size = i+len_max;
pStr = realloc(pStr, current_size);
}
}
pStr[i] = '\0';
printf("\nLong String value:%s \n\n",pStr);
//free it
free(pStr);
pStr = NULL;
}
return 0;
}
Done, now the program can handle unknown size user input easily.
I had this doubt for many days, your solution is so useful, got my solution accepted for all test cases. A BIG Thank you. 🙂
Well, there’s no guarantee that realloc() will return an extesnion of the original buffer (it may very well allocate a new buffer at a completely different address, copy into it the contents of the original buffer, and then return to you a pointer to that new address).
You should also check and handle the case when realloc() fails altogether.
These are the problems already presented briefly by eliasv. Here is a bit more complicated implementation, but hopefully a bit safer and a bit more flexible: https://gist.github.com/migf1/5559176
Why was c initialized to EOF where it was declared as int c = EOF; Why can’t it be left uninitialized at the time of this declaration?
Thanks man! Interesting solution, to use GetChar() in a while loop while allocating the space needed.
Thank you it helped a lot!
How can we get the length of the inputs?
It really helped me.
Thanks a lot! (:
I think you have a couple of bugs.
lets say that for some reason the realloc fails.
now you have 2 bugs:
1. Memory leak:you dont check that the pointer in not NULL -> if you will fail pStr will be NULL but you didn’t free the memory allocated in the beginning.
2. segmentation fault: you will try to assign to the pointer in the next iteration in the loop then you will crash.
assuming we want to handle a very long input this failure is possible.
Thank you very much for this tutorial. I have been trying for 5 days to get an example of this type of program. So concise and clear. Needed this to answer a question in Ivor Horton’s book, Beginning C, 3rd edition,EX 7.2, Page 330.
Awesome solution!
Very useful article.
welcome, actually i’m from java background, recently include in some C development project, hope my sharing is helpful
thanks… this is very informative,.. I am just starting c programming.