stringWithFormat and % not working - iphone

i have this string
NSString *jsonString = #"http://www.soccerway.com/a/block_home_matches?block_id=block_home_matches_14&callback_params=%7B%22date%22%3A%222012-07-31%22%2C%22display%22%3A%22all%22%7D&action=showMatches&params=%7B%22competition_id%22%3A721%7D";
NSLog(#"%#",jsonString);
the output is
http://www.soccerway.com/a/block_home_matches?block_id=block_home_matches_14&callback_params=%7B%22date%22%3A%222012-07-31%22%2C%22display%22%3A%22all%22%7D&action=showMatches&params=%7B%22competition_id%22%3A721%7D
when i use
NSString *linkId = #"448";//not a constant value only for example
NSString *jsonString = [NSString stringWithFormat:#"http://www.soccerway.com/a/block_home_matches?block_id=block_home_matches_14&callback_params=%7B%22date%22%3A%222012-07-31%22%2C%22display%22%3A%22all%22%7D&action=showMatches&params=%7B%22competition_id%22%3A%#%7D",linkId];
the output is
http://www.soccerway.com/a/block_home_matches?block_id=block_home_matches_14&callback_params=7 37040ate23A222㿠 37040isplay23A0x1.21800000507cp-1027ll27D&action=showMatches&params=7 –ompetition_id23A(null) 0
as you see not the same.My question is how to use stringWithFormat to get this result:
http://www.soccerway.com/a/block_home_matches?block_id=block_home_matches_14&callback_params=%7B%22date%22%3A%222012-07-31%22%2C%22display%22%3A%22all%22%7D&action=showMatches&params=%7B%22competition_id%22%3A448%7D
so the value (721) just at the and is replaced by (448)
thanks in advance.

It's because all those % characters inside your format string are being potentially used to used the format arguments, much like %# (see here for details).
This can be seen (for one instance) where:
callback_params=%7B%22date
is transformed into:
callback_params=7 37040ate
In that case, I'm not sure what the %7B is doing since it's not a valid format specifier, but the %22date is resulting in a 22-character decimal value, from %22d, followed by the literal ate.
You need to use %% in your format string if you want a single % in the output string.

The other way of looking at it is that the thing you're giving it as a format string is really data, not purely a format.
To be safe from those spurious conversions, you'd want:
NSString *jsonString = [NSString stringWithFormat:#"%#%#%#", #"http://www.soccerway.com/a/block_home_matches?block_id=block_home_matches_14&callback_params=%7B%22date%22%3A%222012-07-31%22%2C%22display%22%3A%22all%22%7D&action=showMatches&params=%7B%22competition_id%22%3A",linkId, #"%7D"];

Related

I lost % in html source when using stringWithContentsOfUrl

NSString *htmlSource = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlString] encoding:0x80000000 + kCFStringEncodingDOSKorean error:nil];
NSLog(htmlSource);
I get html result tag like (col width="16"/)~~~ but the real html tag is (col width="16%"/)
% character disappears. what is problem?
The string might still contain a %; NSLog() itself gives special significance to a % sign (consider what happens if you use %#, %d, etc.).
Try doing this: NSLog(#"%#", htmlSource); that will log only an object (the string) and keep it out of the formatting argument.

NSString/NSMutableString strange behaviour

OK here is nsmutablestring
data = [NSMutableString stringWithFormat:#"&cb_games%5B%5D="];
Now when ever I try to print or use this string I get big number instead of %5B and %5D not sure why this is happeing any help would be apritiated
thanks
The reason you get unexpected output is that '%' is used as conversion specifier in printf and obviously NSLog and NSString formattings. You need to escape '%' if you don't want it to be interpreted as a conversion specifier. You can escape '%' by preceding it with another '%' like '%%'.
Your string should look like,
#"&cb_games%%5B%%5D="
And the #August Lilleaas's answer is also noteworthy.
Try this:
NSString * data = [NSMutableString stringWithFormat:#"&cb_games%%5B%%5D="];
NSLog(#"%#",data);
stringWithFormat is basically printf, and it attempts to replace your percentages with values that you haven't provided, which is why wierd stuff happens.
[NSMutableString stringWithFormat:#"Hello: %d", 123];
// #"Hello: 123"
If you want a mutable string from a string, try this:
[NSMutableString stringWithString:#"Abc %2 %3"];
// #"Abc %2 %3"
The % is used for string formatting and stuff. I imagine you need to escape the character or something, possibly with a slash.
Did you mean to write?
data = [NSMutableString stringWithString#"&cb_games%5B%5D="]

Splitting a number off prefix of a string on iPhone

Say I have a string like "123alpha". I can use NSNumber to get the 123 out, but how can I determine the part of the string that NSNumber didn't use?
You can use NSScanner to both get the value and the rest of the string.
NSString *input = #"123alpha";
NSScanner *scanner = [NSScanner scannerWithString:input];
float number;
[scanner scanFloat:&number];
NSString *rest = [input substringFromIndex:[scanner scanLocation]];
If it is important to know exactly what is left after parsing the value this is a better approach than trying to trim characters. While I can't think of any particular bad input at the moment that would fail the solution suggested by the OP in the comment to this answer, it looks like a bug waiting to happen.
if your numbers are always at the beginning or end of a string and you want only the remaining characters, you could trim with a character set.
NSString *alpha = #"123alpha";
NSString *stripped = [alpha stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"0123456789"]];
If its starts out as a char * (as opposed to an NSString *), you can use strtol() to get the number and discover where the number ends in a single call.

How do you split NSString into component parts?

In Xcode, if I have an NSString containing a number, ie #"12345", how do I split it into an array representing component parts, ie "1", "2", "3", "4", "5"... There is a componentsSeparatedByString on the NSString object, but in this case there is no delimiter...
There is a ready member function of NSString for doing that:
NSString* foo = #"safgafsfhsdhdfs/gfdgdsgsdg/gdfsgsdgsd";
NSArray* stringComponents = [foo componentsSeparatedByString:#"/"];
It may seem like characterAtIndex: would do the trick, but that returns a unichar, which isn't an NSObject-derived data type and so can't be put into an array directly. You'd need to construct a new string with each unichar.
A simpler solution is to use substringWithRange: with 1-character ranges. Run your string through a simple for (int i=0;i<[myString length];i++) loop to add each 1-character range to an NSMutableArray.
A NSString already is an array of it’s components, if by components you mean single characters. Use [string length] to get the length of the string and [string characterAtIndex:] to get the characters.
If you really need an array of string objects with only one character you will have to create that array yourself. Loop over the characters in the string with a for loop, create a new string with a single character using [NSString stringWithFormat:] and add that to your array. But this usually is not necessary.
In your case, since you have no delimiter, you have to get separate chars by
- (void)getCharacters:(unichar *)buffer range:(NSRange)aRange
or this one
- (unichar)characterAtIndex:(NSUInteger) index inside a loop.
That the only way I see, at the moment.
Don't know if this works for what you want to do but:
const char *foo = [myString UTF8String]
char third_character = foo[2];
Make sure to read the docs on UTF8String

Problem with hash256 in Objective C

when i use this code for generate an hash256 in my iPhone app:
unsigned char hashedChars[32];
NSString *inputString;
inputString = [NSString stringWithFormat:#"hello"];
CC_SHA256([inputString UTF8String],
[inputString lengthOfBytesUsingEncoding:NSASCIIStringEncoding ],
hashedChars);
NSData * hashedData = [NSData dataWithBytes:hashedChars length:32];
The hash256 of inputString, is created correctly, but if i use a string like this #"\x00\x25\x53\b4", the hash256 is different from the real string with "\x" characters.
I think that the problem is in encoding "UTF8" instead of ascii.
Thanks!
I would be suspicious of the first character, "\x00" - thats going to terminate anything that thinks its dealing with "regular C strings".
Not sure whether lengthOfBytesUsingEncoding: takes that stuff into account, but its something I'd experiment with.
You're getting the bytes with [inputString UTF8String] but the length with [inputString lengthOfBytesUsingEncoding:NSASCIIStringEncoding]. This is obviously wrong. Moreover (assuming you mean "\xB4" and that it turns into something not in ASCII), "\xB4" is not likely to be in ASCII. The docs for NSString say
Returns 0 if the specified encoding cannot be used to convert the receiver
So you're calculating the hash of the empty string. Of course it's wrong.
You're less likely to have problems if you only generate the data once:
NSData * inputData = [inputString dataUsingEncoding:NSUTF8StringEncoding];
CC_SHA256(inputData.bytes, inputData.length, hashedChars);