function that returns a string - objective-c

Silly as it may sound, I am trying to write a simple function in objective-c which returns a string and displays it, the following code nearly works but I can't get printf to accept the functions return value ...
NSString* getXMLElementFromString();
int main(int argc, char *argv[])
{
printf(getXMLElementFromString());
return NSApplicationMain(argc, (const char **) argv);
}
NSString* getXMLElementFromString() {
NSString* returnValue;
returnValue = #"Hello!";
return returnValue;
}

NSString* is not equivalent to a traditional C string, which is what printf would expect. To use printf in such a way you'll need to leverage an NSString API to get a null-terminated string out of it:
printf("%s", [getXMLElementFromString() UTF8String]);

You should instead use NSLog() which takes a string (or a format string) as a parameter.
You could use either
NSLog(getXMLElementFromString());
or
NSLog(#"The string: %#", getXMLElementFromString());
Where the %# token specifies an Objective-C object (in this case an NSString). NSLog() works essentially the same as printf() when it comes to format strings, only it will also accept the object token.

I don't know that printf can handle an NSString. Try somethign like:
printf ("%s\n", [getXMLElementFromString()cString]);

Related

Objective-C Noob: How to define + call a method in main?

I wrote a method that works inside of an object, but now I want to extract it so that it's just a function. This is my broken command line tool program:
#import <Foundation/Foundation.h>
+ (NSMutableString *)reverseString:(NSString *)originalString {
NSMutableString *reversedString = [[NSMutableString alloc] init];
for (NSInteger i = originalString.length; i > 0; i--) {
[reversedString appendFormat:#"%c", [originalString characterAtIndex:i-1]];
}
return reversedString;
}
int main(int argc, const char * argv[]) {
#autoreleasepool {
NSString *originalString = #"original string";
NSMutableString *newString = [reverseString:originalString];
NSLog(#"Reversed string: %#", newString);
}
return 0;
}
My question is, how would I call the reverseString method from main()? I don't think I'm defining it properly. Do I have to declare it too? I know that the contents of my method work fine, but I don't know how to define it in a way that allows main to see it.
A "method" is, by definition, part of a class. There are two types, instance methods and class methods. To invoke an instance method, you need, well, an instance of the class. To invoke a class method, you don't need an instance. You can just invoke it directly on a class.
By contrast, there are also "functions". You don't need an instance or a class to invoke a function.
So, it sounds like you want a function. Functions are something that Objective-C inherits from C. The syntax for functions is different from the syntax for methods. Here's how your code might look using a function:
NSMutableString* reverseString(NSString *originalString) {
NSMutableString *reversedString = [[NSMutableString alloc] init];
for (NSInteger i = originalString.length; i > 0; i--) {
[reversedString appendFormat:#"%c", [originalString characterAtIndex:i-1]];
}
return reversedString;
}
int main(int argc, const char * argv[]) {
#autoreleasepool {
NSString *originalString = #"original string";
NSMutableString *newString = reverseString(originalString);
NSLog(#"Reversed string: %#", newString);
}
return 0;
}
By the way, your code does not "work fine". You can't iterate through a string by what it calls "characters" and treat all of them as independent. What NSString calls "characters" are actually UTF-16 code units. Not all Unicode characters can be expressed as single UTF-16 code units. Some need to use two code units in what's called a surrogate pair. If you split up and reverse a surrogate pair, you'll get an invalid string.
As a separate issue, Unicode has combining marks. For example, "é" can be expressed as U+0065 LATIN SMALL LETTER E followed by U+0301 COMBINING ACUTE ACCENT. Again, if you reorder those "characters", the accent will combine with a different character (or fail to combine at all).
The correct way to iterate through the composed character sequences of a string is to use the -[NSString enumerateSubstringsInRange:options:usingBlock:] method with the NSStringEnumerationByComposedCharacterSequences option.
By "I want to extract it so that it's just a function" you're implicitly saying "I want a C-style function, not an Objective-C class method". C-style functions are declared and called differently (blame history).
static NSMutableString * reverseString(NSString * originalString) {
...
}
...
NSMutableString *newString = reverseString(originalString);

objective-c right padding

hello all hope someone can help with that. I was browsing the net and nothing really seems to make sense :S
so I have a string lets say:
"123" and I would like to use a function like:
padr("123", 5, 'x')
and the result should be:
"123xx"
Sorry but Objective-C is a nightmare when dealing with strings :S
You could create your own method to take the initial string, desired length, and padding character (as I was starting to do & also described in a few similar questions)
Or you could use the NSString method Apple already provides ;)
NSString *paddedString = [#"123"
stringByPaddingToLength: 5
withString: #"x" startingAtIndex:0];
See NSString Class Reference for this method.
What about the NSString method stringByPaddingToLength:withString:startingAtIndex:.
NSString* padr(NSString* string, NSUInteger length, NSString *repl)
{
return [string stringByPaddingToLength:length withString:repl startingAtIndex:0];
}
NSMutableString* padString(NSString *str, int padAmt, char padVal)
{
NSMutableString *lol = [NSMutableString stringWithString:str];
while (lol.length < padAmt) {
[lol appendFormat:#"%c", padVal];
}
return lol;
}
And the Call
int main(int argc, const char * argv[]) {
#autoreleasepool {
NSLog(#"%#", padString(#"123", 5, 'x'));
}
return 0;
}

Ask user for information and return that information

I am trying to ask the user to enter their name and then return; "Hello and their name". I know its something simple that I am missing, but I just dont know what it is.
int main(int argc, const char * argv[]) {
#autoreleasepool {
NSString * name = #"";
NSLog(#"What is your name?");
scanf("%#", &name);
NSLog(#"Hello %#",name);
}
}
You're trying to mix Objective-C and C here. This is somewhat tricky to do, but let me see if I can help point you the right direction.
First, change:
NSString * name = #"";
scanf("%#", &name);
to:
char name[64];
scanf("%s", &name);
and see if that works better.
scanf is a C function that works with c types, and NSString is an objective C object which doesn't really work with "scanf".
(The "64" means that there's enough buffer space for 64 characters and if you blow past that, the app will likely crash).
Also, change:
NSLog(#"Hello %#",name);
to this:
NSLog(#"Hello %s",name);
As "%s" in the format tells NSLog that you're passing a C-style string and not a NSString object.
You're using an NSString object in C, which doesn't work. scanf expects a C string. Here's an example:
NSLog(#"What is your name?");
char name[40];
scanf("%s", name);
NSLog(#"Hello %#",[NSString stringWithCString:name encoding:NSUTF8StringEncoding]);
Or you can stay 100% in C:
printf("What is your name?");
char name[40];
scanf("%s", name);
printf("Hello %s", name);

Foundation- returning an NSMutableString

I want to return an NSMutableString in my Foundation program. However, I get the following error:
warning: Semantic Issue: Incompatible pointer to integer conversion
returning 'NSMutableString *' from a function with result type 'int'
for the following code:
int main (int argc, const char * argv[])
{
NSMutableString* result = #"testing";
[pool drain];
return result;
}
That's your main function. As you can see from the declaration int main(), it returns an int. In fact, main() is only allowed to return an int, which indicates failure or success (generally 0 means success and any other number is a program-specific error code). You can't return anything else there — it's just part of the language. If you're trying to print the string, you can use NSLog(#"%#", result) or printf("%s", [result UTF8String]).

Help with C printf function

I am trying to duplicate NSLog but without all of the unnecessary dates at the beginning. I have tried the following c function (I made myself), but it wont log any other values that are not NSStrings. Please could you tell me how I could do it so that it would log any value?
static void echo(NSString *fmt, ...) {
printf("<<<<<<<%s>>>>>>>", [fmt UTF8String]);
}
To use variadic argument lists in C you need to use a few macros that are defined in the stdarg.h header file that comes with your compiler.
here is a detailed explanation of how to write your own printf
If you just want to pass the arguments to the real printf without further manipulation you can use the vfprintf variant of printf instead but you need to extend the fmt parameter separately:
static void echo(NSString *fmt, ...)
{
va_list args;
NSString *logfmt = [NSString stringWithFormat: #"<<<<<<<%s>>>>>>>", [fmt UTF8String]];
va_start (args, fmt);
vfprintf( stdout, [logfmt UTF8String], args );
va_end (args);
[logfmt release];
}