1

Just started programming in Objective-C yesterday with a Java background and I am lost. I have a program that works, and it's purpose is to take in the name, age, and weight of a person from the console and then output those values back to the user. My problem is when I type the data into the console it will only show me the first letter that I type in. Then it will not show me any other characters of my string. So here is some sample console data to demonstrate my point.

Console:

2012-11-14 17:56:05.673 Tutorial[1757:403] Please Enter In Your Name
warning: this program uses gets(), which is unsafe.
C
2012-11-14 17:56:09.494 Tutorial[1757:403] Please Enter Your Age
1
2012-11-14 17:56:11.239 Tutorial[1757:403] Please Enter Your Weight
2
2012-11-14 17:56:13.205 Tutorial[1757:403] 
Name: Chris 
Age: 18 
Weight: 200

As you can see it will only show me the first letter of what I type but it actually uses the enter string. Why on earth is this happening?

Function Declarations:

#import "Person.h"

Person * readPersonData (Person * object);
void writePersonInformation(Person * object);

Main Method:

int main (int argc, const char * argv[])
{
    @autoreleasepool
    {
        Person * p1 = [[Person alloc] init];
        p1 = readPersonData(p1);
        writePersonInformation(p1);
    }
}

Function Implementations:

Person * readPersonData (Person * object)
{
    char nameCharacters[100];
    NSString * objectName;
    int objectAge, objectWeight;

    NSLog(@"Please Enter In Your Name");
    gets(nameCharacters);
    objectName = [[NSString alloc] initWithUTF8String:nameCharacters];
    [object setName : objectName];

    NSLog(@"Please Enter Your Age");
    scanf("%i", &objectAge);
    [object setAge : objectAge];

    NSLog(@"Please Enter Your Weight");
    scanf("%i", &objectWeight);
    [object setWeight : objectWeight];

    return object;
}
void writePersonInformation(Person  * object)
{
    NSLog(@"\nName: %@ \nAge: %i \nWeight: %i", object.getName, object.getAge, object.getWeight);
}
gmustudent
  • 2,229
  • 6
  • 31
  • 43
  • Java programmer here too, but I played enough with objective-c to guess that the problem is that you are mixing c and objective-c. Your char array for example, must be changed for an NSObject subclass. But that is just a guess. Wait for the pro – Bruno Vieira Nov 14 '12 at 23:06
  • @BrunoVieira I thought it might have something to do with my character array as well so I commented the entire bit out and just had the two prompts for the age and weight but the result was the same. This language looks so foreign to me just trying to get a grasp of it all! – gmustudent Nov 14 '12 at 23:08
  • I perfectly understand you. Luckily we have stackoverflow! – Bruno Vieira Nov 14 '12 at 23:10
  • Give a look here: http://stackoverflow.com/questions/7266165/objective-c-simple-string-input-from-console – Bruno Vieira Nov 14 '12 at 23:11
  • @BrunoVieira Objective-C is a C super set so that doesn't matter. It's probably just due to Apple's added some stupid warning to discourage the use of `gets`. Try one of the other C methods for reading command line input. – evanmcdonnal Nov 14 '12 at 23:19
  • @evanmcdonnal No, that's not apple; it's standard with most (all?) compilers. They want you to use `fgets()` where you define the length of the buffer in order to avoid stack overflows (excuse the pun). – trojanfoe Nov 14 '12 at 23:25
  • @trojanfoe That's true that most compilers issue a warning, but my VC compiler issues the warning at compile time, it has no affect on the run time behavior. Showing a warning at run time is some stupid shit that some idiot at Apple thought was a good idea (seriously who does that?). – evanmcdonnal Nov 14 '12 at 23:27
  • @evanmcdonnal Nope. See: http://stackoverflow.com/questions/2973985/why-gets-is-not-working – trojanfoe Nov 14 '12 at 23:28
  • @trojanfoe Maybe it's Unix? I just know VC.exe would give me plenty of warnings for things like using strcpy and doing my own bounds checking and I never got a warning at runtime, only in the build output. – evanmcdonnal Nov 14 '12 at 23:32
  • @evanmcdonnal I expect so; it's wasn't "some idiot at Apple" though, that's for sure. – trojanfoe Nov 14 '12 at 23:34
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/19559/discussion-between-evanmcdonnal-and-trojanfoe) – evanmcdonnal Nov 14 '12 at 23:37
  • So no one knows the answer? Because making it all fgets does not solve my problem. – gmustudent Nov 14 '12 at 23:52
  • @gmustudent Please see my answer. Try it from the command line and post back. – trojanfoe Nov 15 '12 at 00:10

3 Answers3

1

gets() is known to have security issues due to the possibility of a buffer overrun, so the recommendation for quite a while was to use fgets() instead.

RonaldBarzell
  • 3,822
  • 1
  • 16
  • 23
  • Is that the reason why it doesn't echo all of the input? – trojanfoe Nov 14 '12 at 23:24
  • I doubt it, but it won't hurt to get rid of that message anyway. As for the problem, try using a different conversion. initWithCString might do it, but you may also get a deprecated warning. Also, see: http://stackoverflow.com/questions/7884388/proper-way-to-convert-char-to-nsstring-without-initwithcstring – RonaldBarzell Nov 14 '12 at 23:34
  • Looks like your answer is a comment then. – trojanfoe Nov 14 '12 at 23:35
  • I think it's an answer, because one of the issues was the compiler warning. – RonaldBarzell Nov 14 '12 at 23:39
  • Not according to the OP it wasn't. It might be a problem for you (actually it's a problem for me too - I would never have posted the code like that), but it doesn't solve the issue he is having. – trojanfoe Nov 14 '12 at 23:40
1

I think the issue relates to a problem with Xcode 4.5 (see this).

You don't say in your question whether you are running from the debugger console or from the command line, however what happens when you try it from the command line?

You should be using fgets() however, if for nothing else than to stop that runtime warning message.

trojanfoe
  • 120,358
  • 21
  • 212
  • 242
0

Use fgets passing it stdin for the file instead of gets which is generally marked as unsafe by most compilers. This will at least removing the warning which is likely causing the input to not be displayed. Here is a post on how to use fgets

Safe Alternative to gets

Alternatively, you could try to suppress warnings, there is probably some compiler directive to do it (I know there is in VS). I used to do my own bounds checking on a lot of "unsafe" functions and found that to reduce some annoyance from the compiler.

Community
  • 1
  • 1
evanmcdonnal
  • 46,131
  • 16
  • 104
  • 115
  • The question was "My problem is when I type the data into the console it will only show me the first letter that I type in". Does this answer the question? – trojanfoe Nov 14 '12 at 23:27
  • @trojanfoe It doesn't answer why that's happening but I bet you it solves the problem he described. – evanmcdonnal Nov 14 '12 at 23:30
  • @evanmcdonnal removing gets() as in commenting out everything to the prompt to the read does nothing to help my problem. – gmustudent Nov 14 '12 at 23:34
  • @gmustudent I didn't say to stop prompting the user. I said to use `fgets` instead of `gets`. `fgets` has bounds checking, is considered safe, and will not produce that warning. When the warning goes away your problem will probably go with it. – evanmcdonnal Nov 14 '12 at 23:36
  • @evanmcdonnal did what you said, still have the problem. It has nothing to do with gets() – gmustudent Nov 14 '12 at 23:37