I am having trouble assigning the value of an NSString
to a char *
within a structure of a singleton class. The following is a simplification of my problem. My code utilizes more fields in the structure and passes more NSString
s.
我无法将NSString的值分配给单例类结构中的char *。以下是我的问题的简化。我的代码在结构中使用更多字段并传递更多NSStrings。
Say I have a singleton class "SingletonClass" with a structure (I've done my homework with the Apple Documentation and implemented it correctly):
假设我有一个带有结构的单例类“SingletonClass”(我已经完成了Apple文档的作业并正确实现了它):
struct sampleStruct {
char *string1;
//other fields
} struct1;
with this method that sets the value of struct1.string1
to the NSString that was passed:
使用此方法将struct1.string1的值设置为传递的NSString:
- (void)initStructWithString:(NSString *)inputString {
//warning: assignment discards qualifiers from pointer target type
struct1.string1 = [inputString cStringUsingEncoding:NSUTF8StringEncoding];
}
and this method that uses struct1.string1
:
和使用struct1.string1的方法:
- (void)useCharArray {
//I would obviously be doing something more complex in reality
printf("This is the char array: %s", struct1.string1);
//doesn't print the value I assigned to it, but garbage
}
When I call initStructWithString:(NSString *)inputString
from one class and try to call useCharArray
from another class struct1.string1
is a bunch of garbage. During debugging I've confirmed that each class is getting the same instance of this SingletonClass
.
当我从一个类调用initStructWithString:(NSString *)inputString并尝试从另一个类调用useCharArray时,struct1.string1是一堆垃圾。在调试过程中,我已经确认每个类都获得了这个SingletonClass的相同实例。
I'm still learning Objective-C as well as C along the way, so I'm aware it could be a problem with my memory management. I know I [NSString cStringUsingEncoding]
should be assigned to a const char *
and not a char *
, but I don't know how else to go about it since the field in the structure is a char *
. I've tried other approaches within initSructWithString
such as assigning a new const char *
the result of [NSString cStringUsingEncoding]
and then copying that with strlcpy
to struct1.string1
. That approach had the same result.
我还在学习Objective-C和C,所以我知道这可能是我的内存管理问题。我知道我应该将[NSString cStringUsingEncoding]分配给一个const char *而不是char *,但我不知道怎么回事,因为结构中的字段是char *。我在initSructWithString中尝试了其他方法,例如为[NSString cStringUsingEncoding]分配一个新的const char *,然后将strlcpy复制到struct1.string1。这种方法也有同样的结果。
What is the correct technique for storing the value of an NSString
in a char *
within a struct and how can I ensure that the fields within this struct retain their value as the SingletonClass
is used by different classes?
将NSString的值存储在结构中的char *中的正确技术是什么?如何确保此结构中的字段保留其值,因为SingletonClass由不同的类使用?
3 个解决方案
#1
One thing worth noting is that the correct method name would be cStringUsingEncoding:
; and that this string disappears roughly at the same time inputString
does, so the resulting string will have to be copied.
值得注意的是,正确的方法名称是cStringUsingEncoding:;并且这个字符串大致与inputString同时消失,因此必须复制结果字符串。
It might also be worth exploring the use of UTF8String
instead (a convenience method that does the same).
也许值得探索使用UTF8String(一种方便的方法)。
#2
Can't comment yet so writing here (after upping the above Answer)... Just came accross this (I realise it's a few years later) and figured an example might help others to some extent:
还不能发表评论所以写在这里(在提到上面的答案之后)......刚刚来到这里(我意识到这是几年之后)并且想出一个例子可能会在某种程度上帮助其他人:
I'm using this to get the player's name from game center on iOS, I'll have issues with funky characters etc. but my font doesn't support them anyway. ppName is obviously a pointer to a pointer to a char, passed to the method I have this code in.
我正在使用它从iOS上的游戏中心获取玩家的名字,我会遇到时髦角色等问题,但我的字体不支持它们。 ppName显然是指向char的指针,传递给我有这个代码的方法。
*ppName = (char *)malloc(strlen([pPlayer.alias UTF8String]));
strcpy(*ppName, [pPlayer.alias UTF8String]);
#3
If you need to store NSString in a struct, and then from that struct get an NSString back (for example if you needed to send a string to another player in a Game Center Multiplayer Game), you could do it like this :
如果你需要在一个struct中存储NSString,然后从那个struct获取一个NSString(例如,如果你需要在Game Center多人游戏中向另一个玩家发送一个字符串),你可以这样做:
typedef struct {
char stringToSend[20];
int stringToSendLength;
} myStruct;
// create a Struct and an NSString
myStruct aStruct;
NSString *stringToConvert = @"stringToConvert";
// convert NSString into char array
for (int i = 0; i < stringToConvert.length; i++) {
aStruct.stringToSend[i] = [stringToConvert characterAtIndex:i];
}
aStruct.stringToSendLength = stringToConvert.length; // send string length
// store struct into NSData object
NSData *data = [NSData dataWithBytes:&aStruct length:sizeof(myStruct)];
// retrieve data
myStruct *anotherStruct = (myStruct *)[data bytes];
// convert char array into NSString and only keep part required (without some weird random characters)
NSString *receivedString = [[NSString alloc] initWithBytes:anotherStruct->stringToSend length:anotherStruct->stringToSendLength encoding:NSASCIIStringEncoding];
#1
One thing worth noting is that the correct method name would be cStringUsingEncoding:
; and that this string disappears roughly at the same time inputString
does, so the resulting string will have to be copied.
值得注意的是,正确的方法名称是cStringUsingEncoding:;并且这个字符串大致与inputString同时消失,因此必须复制结果字符串。
It might also be worth exploring the use of UTF8String
instead (a convenience method that does the same).
也许值得探索使用UTF8String(一种方便的方法)。
#2
Can't comment yet so writing here (after upping the above Answer)... Just came accross this (I realise it's a few years later) and figured an example might help others to some extent:
还不能发表评论所以写在这里(在提到上面的答案之后)......刚刚来到这里(我意识到这是几年之后)并且想出一个例子可能会在某种程度上帮助其他人:
I'm using this to get the player's name from game center on iOS, I'll have issues with funky characters etc. but my font doesn't support them anyway. ppName is obviously a pointer to a pointer to a char, passed to the method I have this code in.
我正在使用它从iOS上的游戏中心获取玩家的名字,我会遇到时髦角色等问题,但我的字体不支持它们。 ppName显然是指向char的指针,传递给我有这个代码的方法。
*ppName = (char *)malloc(strlen([pPlayer.alias UTF8String]));
strcpy(*ppName, [pPlayer.alias UTF8String]);
#3
If you need to store NSString in a struct, and then from that struct get an NSString back (for example if you needed to send a string to another player in a Game Center Multiplayer Game), you could do it like this :
如果你需要在一个struct中存储NSString,然后从那个struct获取一个NSString(例如,如果你需要在Game Center多人游戏中向另一个玩家发送一个字符串),你可以这样做:
typedef struct {
char stringToSend[20];
int stringToSendLength;
} myStruct;
// create a Struct and an NSString
myStruct aStruct;
NSString *stringToConvert = @"stringToConvert";
// convert NSString into char array
for (int i = 0; i < stringToConvert.length; i++) {
aStruct.stringToSend[i] = [stringToConvert characterAtIndex:i];
}
aStruct.stringToSendLength = stringToConvert.length; // send string length
// store struct into NSData object
NSData *data = [NSData dataWithBytes:&aStruct length:sizeof(myStruct)];
// retrieve data
myStruct *anotherStruct = (myStruct *)[data bytes];
// convert char array into NSString and only keep part required (without some weird random characters)
NSString *receivedString = [[NSString alloc] initWithBytes:anotherStruct->stringToSend length:anotherStruct->stringToSendLength encoding:NSASCIIStringEncoding];