Unexpected behaviour with stringWithFormat:

Discussion in 'Mac Programming' started by Aquis, Nov 12, 2008.

  1. Aquis macrumors member

    Joined:
    Aug 7, 2007
    Location:
    Staffordshire, UK
    #1
    Hello,

    I was merrily programming along when all of a sudden I realised that stringWithFormat had a slightly different way of formatting strings to C's printf, even though the documentation appears to say they both work in pretty much the same way.

    In C with printf:
    Code:
    printf("%1$d %3$d",1,2,3);
    // Prints "1 3"
    
    In Objective-C with stringWithFormat::
    Code:
    NSLog([NSString stringWithFormat:@"%1$d %3$d",1,2,3]);
    // Prints "1 2"
    
    I'd much rather have stringWithFormat: behave like printf, in that it doesn't require the arguments to actually be inside the string...

    Is this a bug, and has anyone else come across this? In any case, is there a quick and easy method to overcome this problem? One thing I thought was just to use printf and something like stringWithCString, but the problem with this is that I'm using %@ as two of the arguments (I only used integers as an example), and obviously printf doesn't support this.

    Any ideas?

    Edit: Also, forgot to say; the string is dynamic (obtained from a strings file)—the only thing I know for sure are three arguments, and not all three have to be used as part of the string!
     
  2. kpua macrumors 6502

    Joined:
    Jul 25, 2006
    #2
    Hmm... this looks like a bug with the '$' symbols. I suggest you report it to bugreporter.apple.com.

    Also, this should be pretty much equivalent to %@, as long as just plain ASCII is used:

    Code:
    printf("%s", [[obj description] cStringUsingEncoding:NSASCIIStringEncoding]);
     
  3. Aquis thread starter macrumors member

    Joined:
    Aug 7, 2007
    Location:
    Staffordshire, UK
    #3
    Perhaps then I will report it! And thanks for the idea as well, it's not plain ASCII, but it shouldn't be too hard to adapt to UTF-16.

    Thanks!
    Aquis
     
  4. gnasher729 macrumors P6

    gnasher729

    Joined:
    Nov 25, 2005
    #4
    Both in C with POSIX extensions and in Objective-C, you must _use_ all the arguments that you supply, otherwise the behaviour is undefined (and undefined behaviour includes that sometimes it might work as intended).

    The reason: You pass parameters to a vararg function, in your case the numbers (int) 1, (int) 2, and (int) 3. These arguments could be of any type. The printf or printf-like function must be able to skip the arguments. It can only skip these arguments if it knows their type, and it knows the type from the format string. In your case, there is no information about the type of the second argument.
     
  5. autorelease macrumors regular

    Joined:
    Oct 13, 2008
    Location:
    Achewood, CA
    #5
    This is true. To quote the printf manpage, "If unaccessed arguments in the format string are interspersed with ones that are accessed, the results will be indeterminate."
     
  6. Aquis thread starter macrumors member

    Joined:
    Aug 7, 2007
    Location:
    Staffordshire, UK
    #6
    Hmm, I guess that make's sense; which is a shame really, since I had plans for interesting things to do with that! I'll look at other ways of doing it; thanks for all your help.
     

Share This Page