.Net vs Cocoa String Formats

时间:2011-01-20 16:18:23

标签: c# .net objective-c cocoa string-formatting

我可以重现以下C#/ .NET:

//A
String.Format("There are {0} cats in my {1} and no {2}", 2, "house", "dogs");
Objective-C / Cocoa中的

//B
[NSString stringWithFormat:@"There are %d cats in my %@ and no %@", 2, "house", "dogs"];

但我不能这样做:

//C
String.Format("I have {0} dogs in my house.  My {0} dogs are very nice, but it is hard to walk {0} dogs at the same time.", numDogs);
Objective-C中的

//D
[NSString stringWithFormat:@"I have %d dogs in my house.  My %d dogs are very nice, but it is hard to walk %d dogs at the same time.", numDogs];

因为它使用printf格式或其他。有更先进的方法吗?有没有办法在字符串解析中做KVC?

这在技术上是我想要的:

[player setValue:@"Jimmy" forKey@"PlayerName"];
//later
[NSString stringWithMagicFormat:@"<PlayerName> sat on a bench in the middle of winter, and <GenderPronoun> felt very cold." andPlayer:player];
// or
[NSString stringwithMagicFormat: playerEnteredStringWithTagInIt andPlayer:player];

但我会满足于:

String.Format(playerEnteredStringWithTagInIt, player.PlayerName, player.PlayerGender, player.GenderPronoun, ...);

谢谢,

3 个答案:

答案 0 :(得分:5)

[NSString stringWithFormat:@"I have %1$d dogs in my house.  My %1$d dogs are very nice, but it is hard to walk %1$d dogs at the same time.", numDogs];

(见man 3 printf。)

答案 1 :(得分:1)

如果您使用的是NSStringstringWithFormat:,那么我认为C99合规性并不适用:stringWithFormat:printf类似,它有自己的实现已经存在了一段时间。

NSLocalizedString()宏实际上会自动为您执行此操作。例如,假设我有以下代码:

 @implementation MDAppController

- (id)init {
    if (self = [super init]) {
        NSArray *catsArray = [NSArray array];
        NSString *string = [NSString stringWithFormat:
         NSLocalizedString(@"There are %lu %@ %@ in my home.", @"no comment"),
        (unsigned long)[catsArray count],
                            NSLocalizedString(@"red", @""),
                            NSLocalizedString(@"cats", @"")];
        NSLog(@"string == %@", string);
    }
    return self;
}

@end

如果我然后在终端

中运行以下内容

/usr/bin/genstrings ~/Developer/NSLocalizedString/MDAppController.m -o ~/Desktop/Strings

(虽然我更喜欢将窗口标题栏中的代理图标拖到我保存在Dock中的AppleScript Droplet上:GenerateStrings.app。它(over)将生成的.strings文件写入〜/ Desktop / Strings / (如有必要,可以创建它。)您可以通过将脚本放到AppleScript编辑器上来编辑脚本。)

它将生成一个UTF16 Localizable.strings文件,您可以将其添加到项目中。在其中它将具有以下内容:

English.lproj / Localizable.strings

/* No comment provided by engineer. */
"cats" = "cats";

/* No comment provided by engineer. */
"red" = "red";

/* no comment */
"There are %lu %@ %@ in my home." = "There are %1$lu %2$@ %3$@ in my home.";

将其复制到西班牙语项目子文件夹并根据需要更改项目的顺序(因为西班牙语形容词通常在名词后面):

Spanish.lproj / Localizable.strings

/* No comment provided by engineer. */
"cats" = "gatos";

/* No comment provided by engineer. */
"red" = "rojos";

/* no comment */
"There are %lu %@ %@ in my home." = "Está %1$lu %3$@ %2$@ en mi casa.";

当英语是我在语言和语言中的主要(最顶层)语言时文本首选窗格:

1/20/2011 12:59:37 PM NSLocalizedString[1777] string == There are 0 red cats in my home.

当西班牙语是我在语言和语言中的主要(最顶层)语言时文本首选窗格:

1/20/2011 12:37:02 PM NSLocalizedString[1702] string == Está 0 gatos rojos en mi casa.

.strings文件在某种意义上是键值对。

有关详细信息,请参阅Resource Programming Guide: String Resources

答案 2 :(得分:0)

我喜欢每个人的答案,但我只是花了15分钟在Docs中找到了我正在寻找的答案......感叹,RTM!这是我的解决方案,以防其他人正在寻找类似的东西。

// Put this in a category of NSString
- (NSString*) stringByReplacingOccurrencesOfKeysWithValues:(NSDictionary*)keyValuePairs
{
    NSString *fStr = self;
    if (keyValuePairs) {
        for (NSString *key in [keyValuePairs allKeys]) {
            NSString *value = [NSString stringWithFormat:@"%@",[keyValuePairs valueForKey:key]];
            fStr = [fStr stringByReplacingOccurrencesOfString:key withString:value];
        }
    }
    return fStr;
}

似乎工作正常,这是我的测试代码:

// testing NSString+Keys
NSMutableDictionary *mud = [NSMutableDictionary dictionaryWithCapacity:1];
[mud setValue:@"Jimmy" forKey:@"{PlayerName}"];
[mud setValue:[NSNumber numberWithInt:97] forKey:@"{HitPoints}"];
[mud setValue:[NSNumber numberWithFloat:1.0678f] forKey:@"{meters}"];
NSString *mystr = [@"Help me {PlayerName} before it is too late! I only have {HitPoints}hp left!  And I am {meters}m away! {PlayerName} hurry!" stringByReplacingOccurrencesOfKeysWithValues:mud];
NSLog(mystr);

输出是:

  

在为时已晚之前帮助我吉米!我只剩下97hp了!而我在1.0678米之外!吉米快点!