Is there a way to specify argument position/index in NSString stringWithFormat?

后端 未结 3 676
南笙
南笙 2020-12-01 01:27

C# has syntax that allows you to specify the argument index in a string format specifier, e.g.:

string message = string.Format(\"Hello, {0}. You are {1} year         


        
相关标签:
3条回答
  • 2020-12-01 01:37

    After doing more research, it appears Cocoa respects positional syntax in printf. Therefore an alternate pattern would be:

    char msg[512] = {0};
    NSString * format = @"Age %2$i, Name: %1$s"; // loaded from resource in practice
    sprintf(msg, [format UTF8String], [name UTF8String], age);
    NSString * message = [NSString stringWithCString:msg encoding:NSUTF8StringEncoding];
    

    However, it would be nice if there was an implementation of this on NSString.

    0 讨论(0)
  • 2020-12-01 01:41

    NSString and CFString support reorderable/positional arguments.

    NSString *string = [NSString stringWithFormat: @"Second arg: %2$@, First arg %1$@", @"<1111>", @"<22222>"];
    NSLog(@"String = %@", string);
    

    Also, see the documentation at Apple: String Resources

    0 讨论(0)
  • 2020-12-01 01:54

    The following code fixes the bug specified in this issue. It is a workaround and renumbers the placeholders to fill gaps.

    + (id)stringWithFormat:(NSString *)format arguments:(NSArray*) arguments 
    {
        NSMutableArray *filteredArguments = [[NSMutableArray alloc] initWithCapacity:arguments.count];
        NSMutableString *correctedFormat = [[NSMutableString alloc ] initWithString:format];
        NSString *placeHolderFormat = @"%%%d$";
    
        int actualPlaceholderIndex = 1;
    
        for (int i = 1; i <= arguments.count; ++i) {
            NSString *placeHolder = [[NSString alloc] initWithFormat:placeHolderFormat, i];
            if ([format rangeOfString:placeHolder].location != NSNotFound) {
                [filteredArguments addObject:[arguments objectAtIndex:i - 1]];
    
                if (actualPlaceholderIndex != i) {
                    NSString *replacementPlaceHolder = [[NSString alloc] initWithFormat:placeHolderFormat, actualPlaceholderIndex];
                    [correctedFormat replaceAllOccurrencesOfString:placeHolder withString:replacementPlaceHolder];    
                    [replacementPlaceHolder release];
                }
                actualPlaceholderIndex++;
            }
            [placeHolder release];
        }
    
        if (filteredArguments.count == 0) {
            //No numbered arguments found: just copy the original arguments. Mixing of unnumbered and numbered arguments is not supported.
            [filteredArguments setArray:arguments];
        }
    
        NSString* result;
        if (filteredArguments.count == 0) {
            //Still no arguments: don't use initWithFormat in this case because it will crash: just return the format string
            result = [NSString stringWithString:format];
        } else {
            char *argList = (char *)malloc(sizeof(NSString *) * [filteredArguments count]);
            [filteredArguments getObjects:(id *)argList];
            result = [[[NSString alloc] initWithFormat:correctedFormat arguments:argList] autorelease];
            free(argList);    
        }
    
        [filteredArguments release];
        [correctedFormat release];
    
        return result;
    }
    
    0 讨论(0)
提交回复
热议问题