What happened to Objective-C's "stringWithFormat:" method? - objective-c

When I define
NSString *testString = [NSString stringWithFormat:#"%4d", 543210];
then testString is #"543210", instead of #"3210"
This used to work in Xcode v4.3.1 but now I upgraded to v4.6 and it stopped working.
Any ideas?

then testString is #"543210", instead of #"3210"
That's the correct behavior anyway. The %Nd format specifier doesn't limit the field with of the number being formatted - it only pads it with space if the field with is greater than the number of characters required to represent the number. If you got 3210 previously, that's erroneous.
If you want to format a number so at most its last four digits are printed, then you can do something like this:
NSString *numStr = [NSString stringWithFormat:#"%d", 543210]; // or whatever
if (numStr.length > 4) {
numStr = [numStr substringFromIndex:numStr.length - 4];
}

Another alternative, has the benefit of being short:
NSString *testString = [NSString stringWithFormat:#"%4d", 543210 % 10000];
The modulus operator % returns the remainder, so if you % 10000 you get the 4 least significant digits.

Related

How to define a variable string format specifier

I have this line of code
// valueX is a long double (long double is a huge floating point)
NSString *value = [NSString stringWithFormat: #"%.10Lg", valueX];
This format specifier is specifying up to 10 decimal digits but I don't want to hard code this to 10.
I have this variable numberOfDigits that I want to be used to define the number of digits. For those itching to down vote this question, it is not so easy as it seems. I cannot substitute the 10 with %# because %.10Lg is a format specifier by itself.
OK, I can create a bunch of strings like #"%.5Lg", #"%.8Lg", #"%.9Lg"... and switch that, but I wonder if there is another way...
There is, if you read the manual pages for format specifiers. You can replace the precision with *, which means it will get taken from a parameter instead.
int numDigits = 10;
NSString *value = [NSString stringWithFormat:#"%.*Lg", numDigits, valueX];
I couldn't find this in the core foundation reference, but I know that this is written in the man 3 printf man page.
Dietrich's answer is the simplest and therefore best. Note that even if there wasn't a built-in way to specify the number of digits with a parameter you could still have done it by first building your format string and then using it:
- (NSString *) stringFromValue: (long double) value digits: (int) digits; {
//First create a format string. Use "%%" to escape the % escape char.
NSString *formatString =[NSString stringWithFormat: #"%%.%dLg", digits];
return [NSString stringWithFormat: formatString, value];
}

How do I convert a decimal to hexadecimal using Objective C?

I've been working on a calculator and I wanted to implement conversions from decimal to octal and from decimal to hexadecimal. I'm new to Xcode and Objective C, but I've managed to get a conversion from decimal to octal, it just doesn't seem to work with hexadecimal.
Here's the code I've written to convert a double to octal:
double result = 0;
...
double decToOct = [self popOperand];
NSString *oct = [NSString stringWithFormat:#"%llo", (long long)decToOct];
result = [oct doubleValue];
Using the same scheme (obviously that includes changing #"%llo" with #"%llx") the conversion to hexadecimal works up to a certain point. It does numbers 0 through 9 just fine, but once it hits 10, it comes up as 0. To test, I also input 5395 and it displayed 1513, the desired result.
Because of this, I can only assume that for some reason my code does not want to input the actual letters of the hexadecimal values (e.g. 11 would convert to B but it shows up as 0) .
Any suggestions? Thanks in advance.
UPDATE:
In addition, I have also been using this to display the result:
double result = [self.brain performOperation:operation];
self.display.text = [NSString stringWithFormat:#"%g", result];
result, as listed from the top, is an argument which is eventually returned here, to self.brain performOperation:operation. This is supposed to handle the display of all operations, including: addition, multiplication, etc. but also octal and hexadecimal. Again, it works fine with octal, but not with hexadecimal.
Try this, May be it will help you. Please do let me know if i am wrong here:--->
NSString *decStr = #"11";
NSString *hexStr = [NSString stringWithFormat:#"%lX",
(unsigned long)[dec integerValue]];
NSLog(#"%#", hexStr);
If you know your string only contains a valid decimal number then the simplest way would be:
NSString *dec = #"254";
NSString *hex = [NSString stringWithFormat:#"0x%lX",
(unsigned long)[dec integerValue]];
NSLog(#"%#", hex);

Dynamically format a float in a NSString

Consider this:
NSString *whatever=[NSString stringWithFormat:#"My float: %.2f",aFloat];
This will round my aFloat to 2 decimal places when building the string whatever
Suppose I want the 2 in this statement to be assignable, such that, based on the value of aFloat I might have it show 2 or 4 decimal places. How can I build this into stringWithFormat?
I want to be able to do this without an if that simply repeats the entire line for different cases, but rather somehow dynamically change just the %.2f portion.
The proper answer is to use an NSNumberFormatter.
However, the easy answer that uses format strings is to use the asterisk specifier. According to the Apple documentation the format string conforms to the IEEE printf specification. This specification states the following:
A field width, or precision, or both, may be indicated by an asterisk ( '*' ). In this case an argument of type int supplies the field width or precision.
This means that
int precision = 2;
NSString *whatever=[NSString stringWithFormat:#"My float: %.*f", precision,aFloat];
// Asterisk in place of 2^^ ^^^^^^^^^ int variable
should work. I have to say, I haven't tried it though, I tend to use NSNumberFormatters.
You will need to build the format first:
NSInteger precision = 2;
NSString *format = [#"My float: %." stringByAppendingFormat:#"%d", precision];
format = [format stringByAppendingString:#"f"];
NSString *whatever=[NSString stringWithFormat:format, aFloat];
Escape % as %% to build format strings:
NSUInteger digits = aFloat > 10.0f ? 2 : 4;
NSString *format = [NSString stringWithFormat:#"My float: %%.%if", digits];
NSString *whatever = [NSString stringWithFormat:format, aFloat];

Padding a number in NSString

I have an int, for example say 45. I want to get NSString from this int padded with 4 zeroes. So the result would be : #"0045". Similar, if the int is 9, I want to get: #"0009".
I know I can count the number of digits, then subtract it from how many zeroes i want padded, and prepend that number to the string, but is there a more elegant way? Thanks.
Try this:
NSLog(#"%04d", 45);
NSLog(#"%04d", 9);
If it works, then you can get padded number with
NSString *paddedNumber = [NSString stringWithFormat:#"%04d", 45];
NSString *otherPaddedNumber = [NSString stringWithFormat:#"%04d", 9];
Update
If you want to have arbitrary number you'd have to create a format for your format:
// create "%04d" format string
NSString *paddingFormat = [NSString stringWithFormat:#"%%0%dd", 4];
// use it for padding numbers
NSString *paddedNumber = [NSString stringWithFormat:paddingFormat, 45];
NSString *otherPaddedNumber = [NSString stringWithFormat:paddingFormat, 9];
Update 2
Please see #Ibmurai's comment on how to properly pad a number with NSLog.
Excuse me for answering this question with an already accepted answer, but the answer (in the update) is not the best solution.
If you want to have an arbitrary number you don't have to create a format for your format, as IEEE printf supports this. Instead do:
NSString *paddedNumber = [NSString stringWithFormat:#"%0*d", 4, 45];
NSString *otherPaddedNumber = [NSString stringWithFormat:#"%0*d", 4, 9];
While the other solution works, it is less effective and elegant.
From the IEEE printf specification:
A field width, or precision, or both, may be indicated by an asterisk ( '*' ). In this case an argument of type int supplies the field width or precision.
Swift version as Int extension (one might wanna come up with a better name for that method):
extension Int
{
func zeroPaddedStringValueForFieldWidth(fieldWidth: Int) -> String
{
return String(format: "%0*d", fieldWidth, self)
}
}
Examples:
print( 45.zeroPaddedStringValueForFieldWidth(4) ) // prints "0045"
print( 9.zeroPaddedStringValueForFieldWidth(4) ) // prints "0009"

Format string, integer with leading zeros

I want to convert an integer value to a string with leading zeroes (if necessary) such that the string has 3 total characters. For example, 5 would become "005", and 10 would become "010".
I've tried this code:
NSString* strName = [NSString stringWithFormat:#"img_00%d.jpg", i];
This partially works, but if i has the value of 10, for example, the result is img_0010.jpg, not img_010.jpg.
Is there a way to do what I want?
Use the format string "img_%03d.jpg" to get decimal numbers with three digits and leading zeros.
For posterity: this works with decimal numbers.
NSString *nmbrStr = #"0033620340000" ;
NSDecimalNumber *theNum = [[NSDecimalNumber decimalNumberWithString:nmbrStr]decimalNumberByAdding: [NSDecimalNumber one]] ;
NSString *fmtStr = [NSString stringWithFormat:#"%012.0F",[theNum doubleValue]] ;
Though this information is hard to find, it is actually documented here in the second paragraph under Formatting Basics. Look for the % character.
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Strings/Articles/FormatStrings.html