How do I take a C string and use it in a label?

Discussion in 'Mac Programming' started by glossywhite, Nov 3, 2009.

  1. macrumors 65816

    glossywhite

    Joined:
    Feb 28, 2008
    #1
    Hi there. Objective C is extremely fiddly and convoluted, in my eyes. I want to take this code:

    Code:
    @implementation appController
    int cnt,rsz=0;
    
    -(IBAction)sendText:(id)sender{
    	[myText setStringValue:[sourceText stringValue]];
    	[myButton setTitle:@"clicked"];
    }
    -(void)windowDidResize:(NSNotification *)winSize{
    	NSLog(@"The window did resize");
    	rsz++;
    	NSLog(@"Window resizes: %i",rsz);
    }
    -(void)windowDidMove:(NSNotification *)winMove{
    	NSLog(@"The window did move");
    	cnt++;
    	NSLog(@"Window moved %i times",cnt);
    }
    -(void)windowDidMiniaturize:(NSNotification *)winMin{
    	NSLog(@"Window went to Dock");
    }
    -(void)windowDidDeminiaturize:(NSNotification *)winUnMin{
    	NSLog(@"Window came from Dock");
    }
    @end
    ... and I want the number of times the window was moved, to be output to a label. I am told I need to do some kind of string conversion :confused: whatever that means, and had some smartass IRC guy keep linking me to Apple's documents, when in fact, all I wanted was a little help (this is why IRC earns it's rep as code snobs!!).

    Please - what do I convert to what, FROM what?. I just want the value stored in 'cnt' to be output to a label - can it be THAT hard to explain?.

    Thanks.
     
  2. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #2
    The docs are actually very good, and i'm going to link them here, but hopefully this will be a bit more helpful:
    http://developer.apple.com/mac/libr.../apple_ref/occ/clm/NSString/stringWithFormat:

    You should be able to get an NSString with the value of your number like this:
    Code:
    NSString *myCntString = [NSString stringWithFormat:@"%d",cnt];
    
    You can then use setStringValue: on the label to set it to myCntString.

    -Lee

    EDIT: There are tons of ways to do this, this is the first that occurred to me... you could do:
    Code:
    NSString *myCntString = [[NSNumber numberWithInt:cnt] stringValue];
    
     
  3. macrumors 603

    whooleytoo

    Joined:
    Aug 2, 2002
    Location:
    Cork, Ireland.
    #3
    You need something like this:

    Code:
    NSString* convertedStr = [NSString stringWithFormat: @"%d", cnt];
    
    "%d" specifies a signed 32-bit int (see here if you want to convert anything other than an int).

    Hope that helps..
     
  4. thread starter macrumors 65816

    glossywhite

    Joined:
    Feb 28, 2008
  5. Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #5
    You can't put method calls outside of a class. They must go inside a class method, such as init.

    You should also declare those as instance variables, not just global.

    And for that warning about NSTextField, use setStringValue: - setTitle: is for buttons.
     
  6. thread starter macrumors 65816

    glossywhite

    Joined:
    Feb 28, 2008
    #6
    ??? could you speak in English please :D

    I got the setTitle part - I worked that out, thanks.
     
  7. macrumors 603

    whooleytoo

    Joined:
    Aug 2, 2002
    Location:
    Cork, Ireland.
    #7
    Wot kainjow said u above.. :)

    You just need to to put that line in a method. So, in windowDidMove, you could update the textfield that shows the cnt variable.

    Edit; too late again!
     
  8. thread starter macrumors 65816

    glossywhite

    Joined:
    Feb 28, 2008
    #8
    Fixed it guys:

    Code:
    #import "appController.h"
    
    
    @implementation appController
    int cnt,rsz,std=0;
    
    
    -(IBAction)sendText:(id)sender{
    	[myText setStringValue:[sourceText stringValue]];
    	[myButton setTitle:@"clicked"];
    }
    -(void)windowDidResize:(NSNotification *)winSize{
    	NSLog(@"The window did resize");
    	rsz++;
    	NSString *myMove = [NSString stringWithFormat:@"Resized: %i times",rsz];
    	[resizedLbl setStringValue:myMove];
    }
    -(void)windowDidMove:(NSNotification *)winMove{
    	NSLog(@"The window did move");
    	cnt++;
    	NSString *myCnt = [NSString stringWithFormat:@"Moved: %i times",cnt];
    	[lbl setStringValue:myCnt];
    }
    -(void)windowDidMiniaturize:(NSNotification *)winMin{
    	NSLog(@"Window went to Dock");
    	std++;
    	NSString *sent = [NSString stringWithFormat:@"Sent to Dock: %i times",std];
    	[sentToDock setStringValue:sent];
    }
    -(void)windowDidDeminiaturize:(NSNotification *)winUnMin{
    	NSLog(@"Window came from Dock");
    }
    @end
    Thanks! :)
     
  9. macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #9
    When you declare instance variables you should do it in the @interface part to make them instance variables of your class. Like local variables for functions, instance variables are for a specific instance of a class.

    The way you have it now, they are global variables.
     
  10. thread starter macrumors 65816

    glossywhite

    Joined:
    Feb 28, 2008
    #10
    Arrgh coding is SO confusing - I'd much rather do industrial design! :(
     
  11. macrumors 6502

    Joined:
    Apr 24, 2008
    #11
    Arrgh industrial design is SO confusing! I have this square peg and this round hole...

    You ran into the computational equivalent. Unfortunately, even for a very young field like software engineering, there's lots of legacy. And it's not always clear what is "better". One camp might say "Let's solve this once and for all. Let's make all pegs round!" whereas the other will say "No, let's standardize on square holes."

    Coding need not be confusing, as long as you take small steps and make sure you really understand what's going on before you take the next.
     
  12. macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #12
    I completely agree. You need to pickup Programming in Objective-C 2.0 by Kochan.
    http://www.amazon.com/Programming-O...=sr_1_1?ie=UTF8&s=books&qid=1257357587&sr=8-1
    If you work through some of the examples in this book you will not make these kinds of mistakes and it will make a whole lot more sense.

    Object oriented programming is not something you jump into like PHP or even C. You need to take some time to learn conceptually why we do things the way we do, so that when you want to start programming things on your own you have an instinctive toolset to accomplish your goals.

    EDIT: on a side note, in my current project I get an odd warning that says "Initialization from distinct Objective-C type" for
    Code:
    NSMutableCharacterSet *setToSkip = [[NSMutableCharacterSet decimalDigitCharacterSet] invertedSet];
    	[setToSkip removeCharactersInString: @"."];
    
    The code works perfectly at runtime, NSMutableCharacterSet is a subclass of NSCharacterSet right? so I should be able to make this call. I guess I don't understand the error, and haven't bothered to play with it since the code snip works.
     
  13. Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #13
    invertedSet returns an NSCharacterSet according to the documentation, so you should double-check to see if that's a bug or not, because if it's not mutable removeCharactersInString would probably fail.

    I'd change it to this:
    Code:
    [[[[NSCharacterSet decimalDigitCharacterSet] invertedSet] mutableCopy] autorelease];
     
  14. macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #14
    I assumed it was something like that, but it certainly works. I'm running a scanner to look for doubles inside a string, and I don't want it to skip . since .25 and 25 are different numbers! I know it doesn't skip . because if the string has no double but has a period it will keep looking for a double indefinitely. (I made a counter to abort scanning if it can't find a double for a set number of tries)

    That said I just noticed NSMutableCharacterSet has an instance method - invert which is even better.

    Because of the fact that it did work before, I assume that NSMutableCharacterSet overrides +invertedSet to return an inverted mutable set.

    EDIT: also if it returned NSCharacterSet instead of NSMutableCharacterSet, it should have an exception at runtime for sending it -removeCharactersInString:. So it's almost certain that it returns a NSMutableChararcterSet. Either way I changed it use -invert then -removeCharactersInString: and it doesn't "warn" me about anything and still runs.
     
  15. thread starter macrumors 65816

    glossywhite

    Joined:
    Feb 28, 2008
    #15
    Do you mean like this?:

    Code:
    #import <Cocoa/Cocoa.h>
    
    
    @interface appController : NSObject {
    	
    	IBOutlet NSTextField *myText;
    	IBOutlet NSButton *myButton;
    	IBOutlet NSTextField *sourceText;	IBOutlet NSTextField *lbl;
    	IBOutlet NSTextField *resizedLbl;
    	IBOutlet NSTextField *sentToDock;
    	
    }
    -(IBAction)sendText:(id)sender;
    int cnt,rsz,std=0;
    @end
     
  16. Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #16
    I don't think you can initialise them in the interface file: you should do this in your init method.
     
  17. thread starter macrumors 65816

    glossywhite

    Joined:
    Feb 28, 2008
    #17
    It's called an .m (main) file, not an interface file, and post #9 said to do what I have done :confused:

    MORE proof that Objective-C is just plain confusing!
     
  18. macrumors 603

    Joined:
    Aug 9, 2009
    #18
    It's not necessary to initialize ivars to 0 or nil. The alloc method guarantees that all ivars in the new object are zeroed. This is described in the basic reference docs.

    Besides that, this is bad form:

    int cnt,rsz,std=0;

    It defines three variables, but only initializes one of them. If the variables are static, they are already initialized to zero (guaranteed by C runtime).

    Finally, if the variables are intended to be ivars, they need to be declared between the {}'s, not outside of them. Re-read the basic reference docs on how to define a class with ivars (instance variables).
     
  19. thread starter macrumors 65816

    glossywhite

    Joined:
    Feb 28, 2008
    #19
    No, in C the above declares all as type INT and gives them ALL the value of 0. As Objective-C is a superset of C, then I see no reason why this won't work, do you? :confused:
     
  20. macrumors 603

    Joined:
    Aug 9, 2009
    #20
    If the variables are static, they are zeroed because static variables default to zero. In other words, removing the initializer would have no effect, because static variables are guaranteed to be zero initially.

    If the variables are local (which they aren't in the given context), then only the last one is initialized. This is true in C, AFAIK. If you can cite a standard that says otherwise, please do.

    If the variables are ivars (which they aren't in the given context), then the initializer again has no effect, because alloc zeros all ivars.
     
  21. macrumors 603

    whooleytoo

    Joined:
    Aug 2, 2002
    Location:
    Cork, Ireland.
    #21
    I would put your instance variables within the braces (as below). I don't know if this is strictly necessary, but I think it's neater/simpler to keep variables and methods separate.

    As for the other issue, I would have guessed chown33 was right, to me your line looks like it's only initialising the last variable.

    But also as he said, you don't need to initialise instance variables to zero; a nice little time-saver.

    Code:
    #import <Cocoa/Cocoa.h>
    
    @interface appController : NSObject {
    	
    	IBOutlet NSTextField *myText;
    	IBOutlet NSButton *myButton;
    	IBOutlet NSTextField *sourceText;	
            IBOutlet NSTextField *lbl;
    	IBOutlet NSTextField *resizedLbl;
    	IBOutlet NSTextField *sentToDock;
            int cnt;
            int rsz;
            int std;	
    }
    -(IBAction)sendText:(id)sender;
    
    @end
    
     
  22. thread starter macrumors 65816

    glossywhite

    Joined:
    Feb 28, 2008
    #22
    So why on EARTH must there be three lines of code, when one would suffice:

    Code:
    #import <Cocoa/Cocoa.h>
    
    
    @interface appController : NSObject {
    	IBOutlet NSTextField *myText;
    	IBOutlet NSButton *myButton;
    	IBOutlet NSTextField *sourceText;	IBOutlet NSTextField *lbl;
    	IBOutlet NSTextField *resizedLbl;
    	IBOutlet NSTextField *sentToDock;
    	int cnt,rsz,std;
    
    }
    
    -(IBAction)sendText:(id)sender;
    
    @end
    
    Just tried it and that works ^^
     
  23. macrumors 603

    whooleytoo

    Joined:
    Aug 2, 2002
    Location:
    Cork, Ireland.
    #23
    You don't strictly need to put each variable on a separate line, you can put them all on one line if you so choose. As a matter of practice, I always put them one per line:

    - Easier to read.
    - Easier to add a comment per variable.
    - Avoids confusion with initialisation, or with pointers.

    E.g.
    Code:
    int* a, b, c;
    
    Is that declaring 3 integer pointers, or one integer pointers and two integers? With one declaration per line, there's never such confusion.

    But use whatever works for you!!
     
  24. Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #24
    It technically is the same, but I'd guess many would prefer them being on their own lines for readability.

    Also, you should avoid naming variables cryptically. Just use "count" instead of "cnt". There is no need to condense everything to save "space" ;)

    I work with someone who likes to keep variable names as short as possible, preferring mysterious acronyms, or suffixing similar variables with a counter (like n, n0, etc.). When working on large projects it gets very old very fast.
     
  25. Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #25
    So why on EARTH must there be twelve lines of code, when two would suffice:
    Code:
    #import <Cocoa/Cocoa.h>
    @interface appController : NSObject {IBOutlet NSTextField *myText; IBOutlet NSButton *myButton; IBOutlet NSTextField *sourceText; 	IBOutlet NSTextField *lbl; IBOutlet NSTextField *resizedLbl; IBOutlet NSTextField *sentToDock; int cnt,rsz,std; } -(IBAction)sendText:(id)sender; @end
    
    ;)
     

Share This Page