Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

TheLee

macrumors member
Original poster
Aug 5, 2006
71
0
Heyo, recent switcher from Windows, and I've been trying my hand at ObjC to see if it's worth porting my C# (and heavy System.Console Library use) to ObjC + SDL.

I've basically been writing more and more complex "Hello, world" programs to get more and more familiar with dynamic typing/binding and some aspects of the Foundation.

so, this is my problem - I'm basically trying to get user input and have the user input define what the object the message is being sent to. Sorry for the ugly code - I was lazy since this was just a test app.
Code:
#import <Foundation/Foundation.h>
#import "hello.h"

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    id helper = NULL;
    SEL selector = NULL;
    
    helper = NSClassFromString(@"Hello");
    selector = NSSelectorFromString(@"print");

    // tests 1 and 2 omitted because, you know, they work

    // this part is for inputting the string without any whitespace
    int bytes;
    char *string;
    
    scanf("%i", &bytes );
    string = (char *) malloc( sizeof(char *) * bytes );
    scanf("%s", string );
    
    printf( "The string was entered with %i bytes.\n", bytes );
    
    // test ot make sure it was inputted correctly
    int i;
    for ( i = 0 ; i < bytes ; i++ )
    {
        printf( "%c.\n", string[i] );
    }

    // test 3
    NSString *nsstring = [[ NSString alloc ] initWithCString:string encoding:NSASCIIStringEncoding ];
    helper = NSClassFromString( nsstring );
    
    if ( helper = nil )
    {
        printf ( "Custom helper failed!\n" );
    }
    
    [ helper performSelector:selector ];
    
    free( string );
    
    [nsstring release];
    [class release];    
    [pool release];
    return 0;
}

The problem is that I'm not getting output... [ Hello print ] is suppossed to output "Hello World" (and is a class method). I've tried printing and testing every single variable, and as far as I can tell, they're all valid and correct. "selector" has not changed from tests 1 and 2, where it correctly was used to send the message of "print." "helper" is non-nil, and the only possible class it can be set to is Hello (unless Apple documentation is wrong... but I also experimented in tests 1 and 2 with @"Hello " and it would give me run-time errors. I also tried doing [ helper print ] but i'm getting no output, so something is clearly wrong with helper... but it's non-nil!

Help!

EDIT - Hmm.. I just noticed that I was inputting "5" and entering Hello, which I expect would give me a segmentation fault of some kind since it has to be null terminated, right? So I tried mallocing to bytes + 1 (to account for the null byte), but the problem persists... I feel C# has something to do with this as it has corrupted my memory of C.
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
I know this is just a test/example, but it might help to forget about malloc() and just declare your string as
Code:
char string[256];
Also, posting your hello class would help a lot. You're using print as if it's a class method, so make sure it's declared like:
Code:
+ (void)print;
in your .h file.
 

HexMonkey

Administrator emeritus
Feb 5, 2004
2,240
504
New Zealand
TheLee said:
if ( helper = nil )

Here's you problem. When this statement is executed, you're setting helper to nil. As nil is equivalent to false, the expression will never evaluate to true so you'll never get the "Custom helper failed" message. Furthermore, you'll never get the "Hello world" message since helper is set to nil.

Change it to this and it should work:

Code:
if ( helper == nil )

TheLee said:
EDIT - Hmm.. I just noticed that I was inputting "5" and entering Hello, which I expect would give me a segmentation fault of some kind since it has to be null terminated, right? So I tried mallocing to bytes + 1 (to account for the null byte), but the problem persists... I feel C# has something to do with this as it has corrupted my memory of C.

Yes, C strings should be allocated 1 byte more than the length of the string. Your program won't always crash if you go past the end of a buffer, but it can cause some quite serious problems. I'll assume you'd never use code like this for anything other than personal use, since it provides no protection against buffer overflows.

As an aside, it's not affecting the behaviour of your program but you're allocating sizeof(char *) for each character in your string. This should be sizeof(char).
 

TheLee

macrumors member
Original poster
Aug 5, 2006
71
0
ZOMG.

I'm such a moron.

yeah, helper = nil was the problem.

C# definitely has spoiled me into laziness as "helper = nil" woudl never have compiled in C# (in case you're not familiar, C# only accepts explicit boolean results (true and false), and not implicit ones like in C where 0 = false and anything else = true).

On another note... if I had done char string[256] and inputted a 5 byte string, would the null termination happen at string[5]? So I don't even need this clumsy construct to prevent whitespace?
 

HexMonkey

Administrator emeritus
Feb 5, 2004
2,240
504
New Zealand
TheLee said:
On another note... if I had done char string[256] and inputted a 5 byte string, would the null termination happen at string[5]? So I don't even need this clumsy construct to prevent whitespace?

Correct. The only change you might want to make to your code is when you print the string character by character; you'd want to stop outputting characters once you reached a null terminator.

ie:
Code:
    int i;
    for ( i = 0 ; i < bytes ; i++ )
    {
		if (string[i]=='\0')
			break;
        printf( "%c.\n", string[i] );
    }
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
TheLee said:
C# definitely has spoiled me into laziness as "helper = nil" woudl never have compiled in C# (in case you're not familiar, C# only accepts explicit boolean results (true and false), and not implicit ones like in C where 0 = false and anything else = true).
That's one thing that annoys me with C#. In Objective-C, you can do if (obj) and it will return true if obj is not nil, and false if it is. But in C# you have to type it out fully, like if (obj == null).. so much extra effort ;)

TheLee said:
On another note... if I had done char string[256] and inputted a 5 byte string, would the null termination happen at string[5]? So I don't even need this clumsy construct to prevent whitespace?
scanf() should put in the null character for you.
 

kpua

macrumors 6502
Jul 25, 2006
294
0
TheLee said:
yeah, helper = nil was the problem.

C# definitely has spoiled me into laziness as "helper = nil" woudl never have compiled in C# (in case you're not familiar, C# only accepts explicit boolean results (true and false), and not implicit ones like in C where 0 = false and anything else = true).

To try to offset this issue, some people try to get in the habit of writing
Code:
if( nil == helper )
so that if you ever do type
Code:
if( nil = helper)
you will get an error.
 

gnasher729

Suspended
Nov 25, 2005
17,980
5,565
kpua said:
To try to offset this issue, some people try to get in the habit of writing
Code:
if( nil == helper )
so that if you ever do type
Code:
if( nil = helper)
you will get an error.

Better method is to figure out what warnings to enable in the compiler, and then make sure that you don't use code that gives any warnings. That way you don't sacrifice readability of your code.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.