return from incompatible pointer types - objective-c

The below code generates the incompatible pointer type error:
char *PLURAL(int objects, NSString *singluar, NSString *pluralised) {
return objects ==1 ? singluar:pluralised;}
I am new to objective-C and programming in general so can some one help me with this error?

An NSString * is not the same as a char * (or "C-string" in Objective C terminology). You can't convert a pointer from one to the other implicitly like that. You'll have to use a method like cStringUsingEncoding. Also, NSString is immutable, so you'll have to return a const char *.
Alternatively, you could simply return the NSString * instead of char *.

Change the return value to NSString* and you should be fine. You are specifying a return value of char* but actually returning NSString*.

Change it to:
NSString *PLURAL(int objects, NSString *singluar, NSString *pluralised) {
return objects ==1 ? singluar:pluralised;
}
char * is not NSString !

Related

Is it a variable or an object? Im very confused

#import <Foundation/Foundation.h>
int main (int argc, char * argv[])
{
#autoreleasepool {
NSString *str = #"Programming is fun";
NSLog (#"%#", str);
}
return 0;
}
In the line
NSString *str = #"Programming is fun";
the constant string object Programming is fun is assigned to the NSString variable str. Its value is then displayed using NSLog .
The NSLog format characters %# can be used to display not just NSString objects, but other objects as well.
/*****/
The previous paragraph was from a book I read, what is really confusing to me is why is he keep using the words variable and objects interchangeably? are objects and varaibles the same thing? so far this is the only confusing part about obj-c to me.
please explain, thank you
An object is an instance of a class. Something that is allocated in memory.
A variable is a name which you use to access something like an object (NSString for example) or a primitive (int for example).
In your case so your object is an instance of NSString, that contains #"Programming is fun":
NSString *str = #"Programming is fun";
The variable to access that object is str.

Casting an (NSString *) to (int *)?

I have an NSString.
NSString *str;
And I need to store it in a struct.
struct {
int *s;
} st;
And set it.
st.s = str;
So, how should I go about retrieving it?
return (__bridge_retained NSString *)st.s;
I've tried the above, and it gives the error: Incompatible types casting 'int *' to 'NSString *' with a __bridge_retained cast.
Answered the question. Simply define the NSString in the struct like this.
struct {
__unsafe_unretained NSString *s;
} st;
Thanks, Carl Veazey!
To store an Objective-C object in an struct you have a couple of options, the one I see most is to store it in the struct as __unsafe_unretained and then maintain a strong reference to it elsewhere.
From the "Common Issues While Converting a Project" section of the ARC Transition Notes:
If using Objective-C objects is sub-optimal, (maybe you want a dense
array of these structs) then consider using a void* instead. This
requires the use of the explicit casts...
They seem to imply __bridge is the way to cast void * to id but are not 100% clear on this.
The other option, which makes more sense to me personally and I've seen more often I think:
Mark the object reference as __unsafe_unretained. ... You declare the
structure as: struct x { NSString * __unsafe_unretained S; int X; }
Hope this helps!

NSString (or NSArray or something) to variable parameter list of C (char *) strings

Is there any easy way to convert an Objective-C holding class of NSStrings into parameters for a function accepting a variable list of char *? Specifically I have a function like:
-(void)someFunction:(NSSomething *) var
that I want to forward to a C function like
void someCFunction(char * var, ...)
Is there an easy way to go about this?
No, you can only do what you want if the number of arguments you're passing is known at compile time. If you just want to convert a single string, use the -UTF8String message:
// Example with two strings
NSString *str1 = ...;
NSString *str2 = ...;
someCFunction([str1 UTF8String], [str2 UTF8String]); // etc.
But if the number of strings will vary at runtime, you'll need to use a different API, if one is available. For example, if there's an API that took an array of strings, you could convert the Objective-C array into a C array:
// This function takes a variable number of strings. Note: in C/Objective-C
// (but not in C++/Objective-C++), it's not legal to convert 'char **' to
// 'char *const *', so you may sometimes need a cast to call this function
void someCFunction(const char *const *stringArray, int numStrings)
{
...
}
...
// Convert Objective-C array to C array
NSArray *objCArray = ...;
int numStrings = [objCArray count];
char **cStrArray = malloc(numStrings * sizeof(char*));
for (int i = 0; i < count; i++)
cStrArray[i] = [[objCArray objectAtIndex:i] UTF8String];
// Call the function; see comment above for note on cast
someCFunction((const char *const *)cStrArray, numStrings);
// Don't leak memory
free(cStrArray);
This would do the trick:
NSString *string = #"testing string"
const char * p1=[string UTF8String];
char * p2;
p2 = const_cast<char *>(p1);
Yes, this can be done, and is explained here:
How to create a NSString from a format string like #"xxx=%#, yyy=%#" and a NSArray of objects?
And here:
http://www.cocoawithlove.com/2009/05/variable-argument-lists-in-cocoa.html
With modifications for ARC here:
How to create a NSString from a format string like #"xxx=%#, yyy=%#" and a NSArray of objects?
Also, variable arguments are not statically or strongly typed, as the other poster seems to be suggesting. In fact, there is no clear indication in the callee of how many arguments you really have. Determining the number of arguments generally breaks down into having to either specify the number by an count parameter, using a null terminator, or inferring it from a format string a la (s)print* . This is frankly why the C (s)print* family of functions has been the source of many errors, now made much much safer by the XCode / Clang / GCC compiler that now warns.
As an aside, you can approach statically typed variable arguments in C++ by creating a template method that accepts an array of an unspecified size. This is generally considered bad form though as the compiler generates separate instances for each size of array seen by by the compiler (template bloat).

Converting char array into NSString object

As per my assignment I have to take in input from a user via a console to be used with NSString.
At the moment I have
char* name[100]; // declaring char array
NSString* firstName; // declaring the NSString
printf("Please enter first name \n");
printf("=> ");
scanf("%s", &name);
firstName = [NSString stringWithCString:name encoding:NSASCIIStringEncoding];
This works, however I am getting this warning
Incompatible pointer types sending 'char [100]' to parameter of type
'const char '
I don't want to be having these errors coming up in the code, I would like to also mention I'm using Xcode 4.2.
Can anyone explain to me why I'm getting these errors, and if I can possibly overcome them?
Many thanks in advance!
Change this:
char* name[100];
to
char name[100];
The first form creates an array of 100 pointers to char. The second one creates an array of 100 char elements. What might be confusing, is that name in that last case, is in fact a pointer, pointing to the first of these 100 char elements.
As printed with NSLog is assigned to initialize a NSString.
NSLog(#"%s", arrayChar);
NSString *str = [NSString stringWithFormat:#"%s", arrayChar];
NSLog(#"Array to String: %#",str);

Why I get: returning const char * from a function with result type char * discards qualifiers

I need te return an NSString as char *:
char *inboxPath (void)
{
NSURL * url = [[[[NSFileManager defaultManager]
URLsForDirectory:NSDocumentDirectory
inDomains:NSUserDomainMask] lastObject] URLByAppendingPathComponent:#"inbox.txt"];
return [[NSString stringWithFormat:#"%#", url] UTF8String];
}
I get: Returning 'const char *' from a function with result type 'char *' discards qualifiers
Why I get this and how I can solve it?
Obviously I don't know much C, is there an easier way to do this?
The function:
char* inboxPath (void);
returns char* while -[NSString UTF8String] returns const char*. The qualifier you're dropping is the const. To solve this, you should declare your function:
const char* inboxPath (void);
Mutating immutable (const) data is one common way to introduce undefined behaviour, so you definitely want to avoid dropping the const qualifier.
If you need a mutable char buffer, make a copy of the utf8 string returned by -[NSString UTF8String].
Add the qualifier to the returned value type in your function:
const char *inboxPath(...)
UTF8String returns a const char *, so you may want to return the same type in your function.