NSString *cell2val= (NSString *) 1;
convert an integer value to nsstring show the following error message
Cast to 'NSString *' of a non-Objective-C to an Objective-C pointer is disallowed with Automatic Reference Counting
You're telling the compiler that 1 is the virtual address of an NSString, which it probably isn't.
I'm guessing you meant to do something like this:
NSString *cell2val = [NSString stringWithFormat:#"%d",1];
You could just construct a string based on the integer.
NSString *cell2val = [NSString stringWithFormat:#"%d",1];
if you were working with NSNumbers you could call stringValue.
Related
I am thinking this is a later Xcode issue (I am using Xcode 11) as this code was fine previously in older versions.
In my main.mm file I have the following;
int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSString * path = [[NSBundle mainBundle] pathForResource: #"fd" ofType: #"dat"];
NSData* image = [NSData dataWithContentsOfFile:path];
const char* szPathName = [path UTF8String];
const char* pos = strrchr (szPathName, '/');
//char* pos = strrchr (szPathName, '/');
*pos = 0;
if (CreateFaceFatted(szPathName) == 0)
{
NSLog(#"Init Dictionary failed");
}
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;
}
I have changed the char* pos = strrchr (szPathName, '/'); to const char* pos = strrchr (szPathName, '/'); as otherwise it would throw a
Cannot initialize a variable of type 'char *' with an rvalue of type 'const char *'
so by doing the const char instead, I at least could proceed further, however on the following part;
*pos = 0;
I receive an error Read only variable is not assignable
I have a small understanding of the c++ code mixed with obj-c but I am struggling to figure a way to get this to compile
You declared the pointer szPathName as a pointer to constant data
const char* szPathName = [path UTF8String];
So you may not change the pointed data using the pointer pos
*pos = 0;
that shall be also declared with the qualifier const because the function strchr returns a constant pointer.
const char* pos = strrchr (szPathName, '/');
Make the pointer szPathName to point to non-constant data.
It doesn't appear that you've done anything since your previous question, SO does really require you show some effort.
Let's step through your original code to hopefully help understanding of the issue:
I am thinking this is a later Xcode issue (I am using Xcode 11) as this code was fine previously in older versions.
It's not an Xcode issue per se, your code was always wrong but fortunately for you producing the desired result, it is just that error and warning messages have improved.
const char* szPathName = [path UTF8String];
This line takes an NSString value referenced by path, calls the method UTF8String on it which returns a pointer to a C string value, and stores that reference in szPathName. From Objective-C you will know that an NSString value is immutable, you cannot change the characters in the string. The UTF8String method returns a pointer to a constant C string value and so szPathName has the type const char * – NSString and const char * are the types in Objective-C and C respectively for variables which store references to constant strings; similarly NSMutableString and char * are the types for references to mutable strings.
char* pos = strrchr (szPathName, '/');
This line of code searches for the rightmost / in the C string and returns a pointer to it. As you found from your last question strrchr() in C++ returns a const char * if passed a const char *. This line of code was always wrong but it seems an earlier compiler did not report the error, which is to type pos as a pointer to a mutable string which it is not. Just as assigning an NSString * value to an NSMutableString * typed variable in Objective-C does not make the referenced string mutable, assigning a const char * value to an char * typed variable in C does not make the reference C string mutable.
*pos = 0;
This line is correct, as the type of pos is char *, but also incorrect as the value stored in pos happens to be a pointer to an immutable C string.
Your code has previously worked as C is lax when it comes to mutability/immutabilty, and fortunately writing into a C string stored inside an instance of NSString (see UTF8String documentation) didn't cause any problems.
You are not going to solve your problem but adding or removing const in various places, doing so may result in code which appears to work but it could easily break at any time.
As suggested to you in your last question rather than try to fix the C code a line at a time, especially given your declared lack of knowledge of C(++), you would be better off looking at what this code is trying to do and to code that as much as possible in Objective-C.
So what is the aim of the code?
Start with a path to a file stored in path, as an NSString value
Determine the parent folder/directory of that file
Pass that parent folder as a constant C string value to the function CreateFaceFatted
You already have the code to obtain the file path and store it in path, so step 1 requires no work.
You also know how to produce a pointer to a constant C string from an NSString value – use UTF8String. So step 3 is covered.
That leaves step 2. Your current code tries to do it after the conversion to a C string, and that you don't know how to do. But you do know Objective-C, is there a method/property on NSString which takes a file path and returns the path of the containing folder/directory? A good place to look would be the documentation.
Hopefully that will help you understand your issue and hence get you quickly to the solution.
I'm writing a custom text-to-speech program that uses SAPI 5, and one problem I'm facing is that enumerating voices with SpEnumTokens and iterating over them produces CSpDynamicString objects.
My question is, how do I convert CSpDynamicString to char * so I could printf them?
It looks like I've to use some kind of text-conversion macro from ATL. I found an example that does this (given dstrDesc is CSpDynamicString):
CSpDynamicString dstrDesc;
SpGetDescription(voiceToken, &dstrDesc);
USES_CONVERSION;
printf("%s\n", W2T(dstrDesc));
However this only prints the first character of the voice name!
Any ideas?
CSpDynamicString implements an operator to convert to WCHAR* and also manages the LPWSTR pointer internally. So, W2T gets you LPTSTR pointer as printf argument. If you have a Unicode build, this is results still in a WCHAR* pointer and printf("%s"... expects CHAR* argument - this is where you can have the problem you are describing.
Try it this way:
CSpDynamicString dstrDesc;
SpGetDescription(voiceToken, &dstrDesc);
printf("%ls\n", (WCHAR*) dstrDesc);
What's the safest way for a NSString to weakly contain a const char * belonging to a std::string? Both examples below work on a simple test, in logs, and as presented in a NSTableView, but I'm concerned about strange behavior down to road. It may be the extra null character of c_str() is simply ignored (because of the length parameter passed) and either will work fine.
Given:
std::string const * stdstring = new std::string("Let's see if this works");
Then:
NSString * aStr = [[NSString alloc] initWithBytesNoCopy:
stdstring->data() length: stdstring->length()
encoding:NSUTF8StringEncoding freeWhenDone:NO];
or:
NSString * aStr2 = [[NSString alloc] initWithBytesNoCopy:
stdstring->c_str() length: stdstring->length()
encoding:NSUTF8StringEncoding freeWhenDone:NO];
or something else?
The documentation for initWithBytesNoCopy:length:... clearly states that the length will be the number of bytes used, so the null termination character will always be ignored. Hence the contents of the memory returned by data() and c_str() is equally suitable.
With that in mind:
The lifetime guarantees of the memory returned by std::string's data() and c_str() functions are identical - they will survive until you call a non-const member function on the string object. It depends on the implementation whether the internal data structure is already a null-terminated character array, so in general, data() will be cheaper or identical in complexity to c_str(). I'd therefore go for data().
Hi
I use the following to convert std::string to NSString but it return (null) while trying to display the value of the nsstring
I need it to return instead of (null) empty at conversion time any suggestion
StudyDate=[NSString stringWithCString:studyDate length:strlen(studyDate)];
any suggestion to avoid null values
best regards
Edit: The syntax #"string" is used only for constructing NSString. With std::string you should use the standard "string" syntax.
NSString* aConstantNSString = #"foo";
const char* aConstantCString = "foo";
std::string aConstantStdString = "foo";
CFStringRef aConstantCFString = CFSTR("foo");
+stringWithCString:length: has been deprecated since the very early beginning of the iPhone SDK. If the string contains only ASCII characters, often you could use +stringWithUTF8String: instead.
Your method works only when studyDate is a C string (i.e. const char*), but you said you have a std::string. There is no method to directly convert a std::string into an NSString. You must use .c_str() to create the C string first:
StudyDate = [NSString stringWithUTF8String:studyDate.c_str()];
(But the above shouldn't be the cause you're getting (null) because passing a std::string to +stringWithCString:length: or even strlen should give a compile-time error immediately.
'error: cannot convert ‘std::string’ to ‘const char*’ in argument passing'
So studyDate should already be a const char*. We need more context (code) to see what's going on.)
NSString objCString = #"this is my objective c string";
std::string cppString; // this is your c++ string or however you declared it blah blah blah
cppString = [objCString UTF8String];
// this is the conversion of an NSString into a c++ string
// not sure if it will work for c strings but you can certainly try
thats all there is too it im afraid. all you need is just that one line of code. this was done in ios sdk 4.3 btw so im not sure if the coding will change if you appiled it elsewhere.
I wonder which method would be better to convert const char* string to NSString.
I found there are some facts.
[NSString stringWithCString:length:] is kind of deprecated.
[NSString stringWithCString:encoding] may be used for my purpose
But I want to convert with length AND encoding(because I want to make that fine if I have some Non-ASCII character by setting encoding to UTF-8). Any thoughts?
I just think now
create other char and copy with length by using std::strncpy(ch1, ch2, len)
use [NSString stringWithCString:encoding:]
But it doesn't work well.
If your const char* variable is named foo (and it points to a null-terminated string), just say
[NSString stringWithUTF8String:foo]
Because UTF-8 is a superset of ASCII, this will work whether foo points to UTF-8 or ASCII. Then you can move up to full Unicode with no problems.
Use:
[NSString initWithBytes:length:encoding].