Puts and printf in C

I am new to C. And I found some problem in puts and printf from C.

char str[10]; printf("Input a string.\n"); gets(str); printf("The string you input is: %s",str); 

The result is if I set more than 10 char

 1ang:lab lang$ ./exercise Input a string. warning: this program uses gets(), which is unsafe. 0123456789 Abort trap: 6 

But when I add \n to the end of printf, printf("The string you input is: %s\n",str); The conclusion is different.

 1ang:lab lang$ ./exercise Input a string. warning: this program uses gets(), which is unsafe. 0123456789 The string you input is: 0123456789 Abort trap: 6 

It will print a line first, and then an error will appear. Can anyone explain this?

+5
source share
4 answers

You have not reserved enough space for your row.

Remember that you need an extra element for null-terminator ( \0 ), which is added to the character array. str[10] not large enough.

Since the str argument to printf does not contain \0 , it overflows the buffer with undefined results.

Unilaterally consider using fgets . In its current form, but even preserving sufficient memory for your test string, you can easily provide a longer version that will again crash your program.

Also, consider adding \n to the printf line: this newline character clears the output buffer to help you write back to the console in a timely manner.

+7
source

gets unsafe, in your code, I think it overwrites part of your stack, possibly the case of the returned pointer (I'm not sure of the name).

Now, why do you have a message in the case, and not in another?

Because printing "\n" in printf will force the buffering stream so far.

In the first case, an accident occurs before the text is displayed on your console, but if you use the debugger, you will see that it occurs at the same point.

+2
source

Your compiler told you: " warning: this program uses gets () , which is unsafe. ", But you went ahead anyway. Then you read enough data to overflow your array, presumably damaging another repository.

What happens next is undefined behavior, and anything can happen. In your case, it seems that printf succeeds, but the damage causes the subsequent code to fail (possibly returning from the function). If you reset stdout (which happens implicitly when printing \n , if stdout is a terminal), you will see the output. If you did not do this, buffered output will be lost when the process is destroyed.

+1
source

You have a great example of undefined behavior. It is not determined what will happen if you exceed the size of the bufferd array. As others have pointed out, you should not use gets . A function is not considered deprecated for no reason. Better use fgets or fscanf .

I would also recommend writing a "safe" input function using the return value of scanf . Or you can use a combination of fgets and sscanf to read entire lines from input and then use the read line after sscanf , as in this one .

0
source

Source: https://habr.com/ru/post/1243653/


All Articles