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

后端 未结 3 687
南笙
南笙 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: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;
    }
    

提交回复
热议问题