PDA

View Full Version : gets(), tell Xcode to compile, even when its unsafe




darxun
Mar 18, 2008, 11:39 AM
By using gets() with C in xCode, I always have to read, that I'm using an unsafe function. I know that it is unsafe and i don't want to use a different function (at university they told us to do so).
xCode wouldn't compile my code for me, so that ist works completly. There's no mistake in the code, because it works fine in VisualStudio.

My question is, how do I tell xCode that I want to have compiled my code, no matter wether gets is unsafe or not?

Here is it (sorry there are many german words in it^):




BTW: I want to use my new MacBookAir in University, I really like xCode and don't want to install Parallels or somthing, so please don't tell me to install ann Microsoft software.



TEG
Mar 18, 2008, 11:45 AM
I had the same problem and it compiled just fine, just gave the unsafe error. I would suggest looking for compiler preferences, or use gcc in the terminal to do your compiling, as that is what I do.

TEG

darxun
Mar 18, 2008, 12:33 PM
I'm sorry, i was wrong, of course it does compile, but in the console (where I then can choose between the two cases) it gives en error saying that "gets" is unsafe and just jumps over the rest of my programm so that I won't come to use the function "void StringEinlesen(char *szString)" to read a String.

So thats actually my Problem^^

Heres what I see in the console after choosing case 1 and pressing enter.

Wollen Sie...
(1) ...eine Quersumme berechnen?
(2) ...die Teiler bestimmen?
1
warning: this program uses gets(), which is unsafe.
Bitte geben Sie eine nat¸rliche Zahl ein:Quersumme ist: 0
Sie haben diese Zahl eingegeben:

iSee
Mar 18, 2008, 01:02 PM
I'm not sure the warning is what's causing your gets() call to be "skipped."

You are doing a scanf("%d", ...) followed by gets(...)
The user types "1" followed by the enter key.
The "1" is consumed by the scanf(), but gets() reads the rest of the line. The rest of the line is empty, so gets() reads an empty string.

I think you intend the call to fflush(stdin) right after the scanf() to take care of this, but the behaviour of fflush() is not defined for input streams. So, it may seem to work on some systems or for some input sets, but not for others. You could use something like "gets(szString);" right after the scanf() in place of fflush().

Also, if your professor allows it, use fgets() on stdin instead of gets()--using gets() really is bad programming practice.

Edit: OK, I looked up fflush() on the Apple man pages and it does say that it will consume any buffered input on an input stream. So it should work as you expect (on OS X anyway). So I don't know what the problem is. :( I feel bad for leading you astrsy, though, so if this is still open, I'll look in to if further tonight, when I'm on my Mac. Good luck!

darxun
Mar 19, 2008, 03:31 AM
I think you intend the call to fflush(stdin) right after the scanf() to take care of this,

I actually put the fflush there, because otherwise, the programm would skip scanf(). I was told to use fflush in this case. He said that some buffer has to be empty, so that scanf() can write its input in this buffer.

(ATM I'm not at my Mac, so I'll try it out tonight^^, the more I'm working at this problem, the more I want to fix it, it is really annoying. I had it running one VisualStudio!)

darxun
Mar 20, 2008, 03:15 AM
In xCode fflush surprisingly doesn't have any influence on my problem. I'm still getting the same error-message.

So what can I try next?

CaptainZap
Mar 20, 2008, 07:56 AM
Why is gets() unsafe??

iSee
Mar 20, 2008, 09:06 AM
Because it writes the input to a buffer of fixed size. But it doesn't know the size of the buffer, so it just writes as much input as it gets. If it gets more input than the buffer can hold, it just continues writing past the end of the buffer.

It that happens by accident, usually the worst that will happen is the app will crash. If it is done maliciously, it can be used to inject new code in to a running app. That could let an attacker take over your machine or steal or destroy data, etc.

fgets() lets the programmer specify the size of the buffer so fgets() knows to to stop writing when it gets to the end.

lazydog
Mar 20, 2008, 10:09 AM
Hi, I got your program to work by putting in an extra scanf() like this:-


void StringEinlesen(char *szString)
{

scanf( "\n" ) ;
//here its annyoing me with telling it's unsafe...
gets(szString);
printf( "you entered %s\n", szString ) ;
}


Still got the warning printed though.

b e n

darxun
Mar 20, 2008, 01:14 PM
Oh, thanks a lot! I posted this problem in four forums, no I'm getting an answer. :D

But why does it only work with this scanf(), actually this is not necessary. Do you also know why it works this way?

iSee
Mar 20, 2008, 01:41 PM
The extra scanf() consumes the newline character.

Think of it this way:

If the user types the one key, followed by the enter key, STDIN is "1\n" ('1' followed by the enter key)

What was happening:
1. Your scanf("%d") consumes '1', but leaves the '\n'
2. Later your gets() is called. gets() reads til the next newline character. It finds the newline in STDIN as the first thing, so it reads that as a blank line.

What happens with the additional scanf("\n"):
1. Your scanf("%d") consumes '1', but leaves the '\n'
2. scanf("\n") consumes the '\n', leaving STDIN empty.
3. Later your gets() is called. With the newline gone, it waits for the user to type a line of text.