Is the gets() string function in C considered a bad practice? [duplicate] - c

This question already has answers here:
Why is the gets function so dangerous that it should not be used?
(13 answers)
Closed 6 years ago.
was reading the Head first C book and stumbled across the author saying gets() to be a bad practice
gets() is a function that’s
been around for a long time.
But all you really need to know
is that you really shouldn’t
use it.
why is it considered a bad practice?

Consider
#include<stdio.h>
int main()
{
char buffer[100];
gets(buffer);
printf("The input is %s",buffer);
}
When user types input of length within 99 then there is no problem. But when user types more than 99 characters it tries to write into memory it doesn't own.
The worst thing is it causes abnormal behaviour and the program terminates without any information which leaves user baffled about the current situation
An alternative way is to use char *fgets(char *s, int size, FILE *stream); function
Update: As pointed by #pmg : gets() removes newline while fgets() retains the new line

gets is prone to buffer overruns (i.e. memory corruption etc).
fgets over comes this by having passing in the size of the buffer

Related

Why doesn't my first gets() work? I have some of them and codeblocks always forgets the first one?

I'm using gets() cause it's a jomework and we are told to.
It acts like I'd have no gets(&a)...
` char a,b,c;
switch(x);
case '1':printf("Please enter the author\n");
printf("Author:");
gets(&a);
printf("\nTitle:");
gets(&b);`
Why doesn't my first gets() work?
gets(char *); expects a pointer to a place to form a non-zero length string.
char a in only big enough for a zero length "" string.
gets(&a); is buffer overflow - research undefined behavior.
"I'm using gets() cause it's a jomework and we are told to." --> Sorry your school/work is so. Recommend researching for a better school.

program to find length of a string [duplicate]

This question already has answers here:
Program didn't crash when buffer overflow
(2 answers)
Closed 6 years ago.
If I input string of more than size 10 then why is not generating compile time error as I have declared str of size 10? For example I have input welcome to the world, then it is compiling and running with no error.
#include <stdio.h>
#include <conio.h>
int main() {
int i = 0, length;
char str[10];
printf("enter string: ");
gets(str);
while (str[i] !='\0') {
i = i + 1;
}
length = i;
printf("the length of string is %d", length);
}
An input string is a runtime entity. Any computation involving it cannot be performed at compile time, so the best you can do is raise a runtime error.
Furthermore, gets is marked deprecated in C99 and simply removed from C11 because exactly this insecure behavior cannot be prevented: without anyone complaining, you can write beyond array bounds, which is undefined behavior. Use fgets instead, which provides a higher level of security.
Because gets does not take a length parameter it does not know how large your input buffer is.
you can use fgets instead
It is a undefined behaviour. Anything can happen.
Never use gets() because it does not prevent buffer overflowing which is what your program is doing. Use fgets() instead of gets().
fgets() prevent the size of array beyond that.
fgets(array, sizeOfArray, stdin);
Because you defined the string length as 10, so if the value increases the program stops executing, moreover you have not made handling error mechanism for the code. So resulting the following error you mentioned. Use fgets

inputting a character string using scanf()

I started learning about inputting character strings in C. In the following source code I get a character array of length 5.
#include<stdio.h>
int main(void)
{
char s1[5];
printf("enter text:\n");
scanf("%s",s1);
printf("\n%s\n",s1);
return 0;
}
when the input is:
1234567891234567, and I've checked it's working fine up to 16 elements(which I don't understand because it is more than 5 elements).
12345678912345678, it's giving me an error segmentation fault: 11 (I gave 17 elements in this case)
123456789123456789, the error is Illegal instruction: 4 (I gave 18 elements in this case)
I don't understand why there are different errors. Is this the behavior of scanf() or character arrays in C?. The book that I am reading didn't have a clear explanation about these things. FYI I don't know anything about pointers. Any further explanation about this would be really helpful.
Is this the behavior of scanf() or character arrays in C?
TL;DR - No, you're facing the side-effects of undefined behavior.
To elaborate, in your case, against a code like
scanf("%s",s1);
where you have defined
char s1[5];
inputting anything more than 4 char will cause your program to venture into invalid memory area (past the allocated memory) which in turn invokes undefined behavior.
Once you hit UB, the behavior of the program cannot be predicted or justified in any way. It can do absolutely anything possible (or even impossible).
There is nothing inherent in the scanf() which stops you from reading overly long input and overrun the buffer, you should keep control on the input string scanning by using the field width, like
scanf("%4s",s1); //1 saved for terminating null
The scanf function when reading strings read up to the next white-space (e.g. newline, space, tab etc.), or the "end of file". It has no idea about the size of the buffer you provide it.
If the string you read is longer than the buffer provided, then it will write out of bounds, and you will have undefined behavior.
The simplest way to stop this is to provide a field length to the scanf format, as in
char s1[5];
scanf("%4s",s1);
Note that I use 4 as field length, as there needs to be space for the string terminator as well.
You can also use the "secure" scanf_s for which you need to provide the buffer size as an argument:
char s1[5];
scanf_s("%s", s1, sizeof(s1));

Unknown length of input [duplicate]

This question already has answers here:
How can I read an input string of unknown length?
(11 answers)
Closed 7 years ago.
There are several ways how to retrieve string input, e.g getline() , or fgets() but all of them require size of the string as an argument. But what if i want to retrieve string of unknown size? How is it possible using getline() or fgets() in C?
The answer is no. You can't read a string of indeterminate length. You can, however, read one character at a time until you reach the size of the storage space you have allocated in your program. Use fgetc in a loop.
int fgetc(FILE *stream)
Open the stream , read one character at a time, and stop reading when you see your sentinel character, which is probably a newline.

Inputting an arithmatic statement in c and return the value [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
(I am very bad at inputting/processing strings in C. Hope this question will teach me a lot.)
I am trying to make a function that will input an arithmatic string from stdin, e.g 23 + 45 * 6 - 5, and return the value.
There are multiple strings, entered one after another, and can be of any length and the operator precedence doesn't matter, i.e., it processes string sequentially.
The problems that I faced are :-
\n from previous string is also considered a string.So if I input 3 strings , it will actually be 6, 3 strings and 3 \n.
I used a char pointer and used char * input; scanf(" %s",input);, but in addition to above problem, I also get segmentation fault, which I guess is due to missing \0.
My question is forget what mess I did, what would you have done or what's the best way to handle string input in the above scenario. A dummy code is sufficient.Thanks.
What I was doing
#include <stdio.h>
int main()
{
int t; //no of test cases
char input;
scanf("%d",&t);
while(t--)
{
while((input=getchar())!='\n')
{
//use switch to identify char and follow appropriate action
printf("%c\n",input );
}
}
return 0;
}
As suggested by Joachim Pileborg, use fgets. Use a char array, instead of one char variable, to store the string.
char input[100];
fgets(input, sizeof(input), stdin);
The advantage of fgets over sscanf is that fgets can read spaces in your input.
It will include the end-of-line byte \n, so 3 strings will not turn into 6 strings.
As usual with fgets, there is an arbitrary limit on the length of the input. If the user inputs something longer than 98 bytes, the system cannot fit it all (plus end-of-line \n and end-of-string \0 bytes), and the program will receive truncated string.
If you cannot tolerate that, use getline (it's harder to use, so use fgets if in doubt).
After you scan your string in, check to see if it is a '\n', if it is just ignore processing it and move to the next one.
Or you could try:
char input[101];
scanf("%s\n", &input);
First of all. Your idea of writing an fomular expression analyzer as a first projekt is not a very good one. Start with a simpler project.
You get the sagmentation fault, because you try to read data (with the scanf()) into a not initialized pointer.
char *input;
will not allocate any memory for the string you want to read with scanf(). You have to use a buffer something like
char input[256];
and give the pointer to the buffer to scanf("%s",input) (oder for better understanding scanf("%s",&input[0]);
Anywhere, this buffer has only 255 chars to store and you must be aware, that if you enter more then 255 chars in the scanf() you will get an illegal memory access as well.
Claus

Resources