如何在Objective-C的结构中将NSString的值存储为char数组?

时间:2023-02-08 22:54:20

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 NSStrings.

我无法将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];