Objective-C: Improve function - objective-c

I´m new to developing apps and I would like to have some hints about the code I have here:
- (IBAction)button_increase_click:(id)sender {
int number = [self.label_content.text intValue];
number+=1;
NSString *increased_value = [NSString stringWithFormat:#"%d",number];
int count = [increased_value length];
while (count<4) {
increased_value = [NSString stringWithFormat:#"%#%#", #"0",increased_value];
count = [increased_value length];
}
self.label_content.text = increased_value;
}
What I need to do is to increase the value of "label_content" by 1 and fill it with leading zeros until it has reached 4 digits. eg "0001" "0013" "0132".
So how can I improve the above code and take care of its readability?
Thank you for helping me out.

The method can look like this:
- (IBAction)button_increase_click:(id)sender {
int number = [self.label_content.text intValue];
number++;
self.label_content.text = [NSString stringWithFormat:#"%04d", number];
}
Update For increasing readability use camel case for ivar method and other names. It's standard for iOS.
- (IBAction)increaseValue:(id)sender {
int number = [self.contentLabel.text intValue];
number++;
self.contentLabel.text = [NSString stringWithFormat:#"%04d", number];
}

See Apple's String Format Specifiers Documentation.
A better number formatter:
int number = 4;
[NSString stringWithFormat:#"%04d",number];
NSLog(#"number: %04d", number);
NSLog output:
number: 0004

Related

Count number of zero(0) using objective-c

I want to count how many number of zero(0) before numeric number. Because I need to save those number which is present before numeric.
Exam:- suppose I have a number 0000102. So I want to calculate how many zero(0) before numeric start. In this exam we are see here is 4 zero's(0) are present. It is possible to calculate this?
for (i=0;i<string.length;i++)
{
if ([[string characterAtIndex:i] intValue] <= 9 || [[string characterAtIndex:i] intValue] > 0 )
{
i++;
}
else
{
numerOfZeros++;
}
}
int count = 0;
NSString *strr = #"0000102";
unichar findC;
for (int i = 0; i<strr.length; i++)
{
findC = [strr characterAtIndex:i];
if (findC == '0')
{
count++;
}
else
break;
}
NSLog(#"%d",count);
Recursive approach for a one liner:
#implementation NSString (category)
- (NSUInteger)zeroPrefixCount
{
return [string hasPrefix:#"0"] ? 1 + [[string substringFromIndex:1] zeroPrefixCount] : 0;
}
#end
This is not an optimal solution, performance-wise, but it's typical of your first days at programming classes.
usage
// x will be 4
NSUInteger x = [#"0000102" zeroPrefixCount];
I recommend you to save this kind of numbers as String itself and no need to further evaluate how many zeros are there rather do a string comparison if needed.
If you really want to count zeros in your number then you can consider converting it to a string and use NSRange and NSString helper methods to get what you want. Similar situation is answered here.
search if NSString contains value

Convert NSString value to int

That may sound odd.
I got an NSString value NSString * numb = [self.dataDict valueForKey:#"id"]; and i know, that is it some kind of integer (for example, i need that integer to comparison - if val less or equal then something). I need to know what integer is it.
What i've tried:
NSNumber *numba = [self.dataDict valueForKey:#"id"];
NSLog output - numba is 2038735264
And actually that was 428.
is there any way to achieve the point? Thanks!
That is piece of responseObject:
(
{
id = 3;
dog = "\U041a\U0430\U043a\U043e\U0439-\U0442\U043e \U043c\U0443\U0434\U0430\U043a \U043d\U0430\U043a\U0440\U0443\U0442\U0438\U043b";
image = "cute_dog/116.jpg";
score = 586;
},
{
id = 115;
dog = "\U0422\U0430\U043d\U044f \U041a\U043b\U044e\U043a\U0432\U0438\U043d\U0430";
image = "cute_dog/115.jpg";
score = 481;
},
There are a number of methods you can use to convert an NSString to a number. What numeric type would you like?
NSString *string = self.dataDict[#"id"];
int intValue = string.intValue;
NSInteger integerValue = string.integerValue;
long long longLongValue = string.longLongValue;
Trying something like this.
NSNumber *numba = [NSNumber numberWithInt[self.dataDict valueForKey:#"id"]];
//For string
NSString *stringValue = [numba stringValue];
//For integer
NSInteger integer = [numba integerValue];

Comparing string to a character of another string?

Here's my program so far. My intention is to have it so the if statement compares the letter in the string letterGuessed to a character in the string userInputPhraseString. Here's what I have. While coding in xCode, I get an "expected '['"error. I have no idea why.
NSString *letterGuessed = userInputGuessedLetter.text;
NSString *userInputPhraseString = userInputPhraseString.text;
int loopCounter = 0;
int stringLength = userInputPhraseString.length;
while (loopCounter < stringLength){
if (guessedLetter isEqualToString:[userInputPhraseString characterAtIndex:loopIndexTwo])
{
//if statement true
}
loopCounter++;
}
You are missing enclosing square brackets on this line:
if (guessedLetter isEqualToString:[userInputPhraseString characterAtIndex:loopIndexTwo])
It should be:
if ([guessedLetter isEqualToString:[userInputPhraseString characterAtIndex:loopIndexTwo]])
Edit that won’t fix your problem, though, because characterAtIndex: returns a unichar, not an NSString.
It's not clear what you are trying to do.. But I suppose that letterGuessed has one character... And that userInputPhraseString has many characters. So you want to know if letterGuessed is inside userInputPhraseString correct?
This is one solution without loops involved.. I replaced the input with fixed values for testing and tested the code.. It works.
NSString *letterGuessed = #"A"; //Change to your inputs
NSString *userInputPhraseString = #"BBBA"; //Since it has A it will be true in the test
NSCharacterSet *cset = [NSCharacterSet characterSetWithCharactersInString:letterGuessed];
NSRange range = [userInputPhraseString rangeOfCharacterFromSet:cset];
if (range.location != NSNotFound) { //Does letterGuessed is in UserInputPhraseString?
NSLog(#"YES"); //userInput Does contain A...
} else {
NSLog(#"NO");
}
In regards to your code... I fixed a couple of errors, first you are trying to get a UniChar (Integer) value for the character and want to compare it to a NSString which is an Object. Also fixed a couple of issues with syntax you had and used the right approach which is to return a range of characters. Again for doing what you want to accomplish the example above is the best approach I know, but for the sake of learning, here is your code fixed.
NSString *letterGuessed = #"A"; //Change to your inputs
NSString *userInputPhraseString = #"BBBA"; //Since it has A it will be true in the test
NSInteger loopCounter = 0; //Use NSInteger instead of int.
NSInteger stringLength = userInputPhraseString.length;
BOOL foundChar = NO; //Just for the sake of returning NOT FOUND in NSLOG
while (loopCounter < stringLength){
//Here we will get a letter for each iteration.
NSString *scannedLetter = [userInputPhraseString substringWithRange:NSMakeRange(loopCounter, 1)]; // Removed loopCounterTwo
if ([scannedLetter isEqualToString:letterGuessed])
{
NSLog(#"FOUND CHARACTER");
foundChar = YES;
}
loopCounter++;
}
if (!foundChar) NSLog(#"NOT FOUND");
NSRange holds the position, length.. So we move to a new position on every iteration and then get 1 character.
Also if this approach is what you want, I would strongly suggest a for-loop.

How to trim zeros after decimal point

I am trying to trim zeros after a decimal point as below but it's not giving desired result.
trig = [currentVal doubleValue];
trig = trig/100;
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setMaximumFractionDigits:0];
display.text = [formatter stringFromNumber:[NSNumber numberWithDouble:trig]];
The number is still being displayed without trimming zeros after the decimal point.
Here currentVal is the number I am entering.
For example if i pass "trig" = 123 (Initially "trig" = 123 after doing trig/100 i want to display 1.23 but it is displaying as 1.23000000).
Sometimes the straight C format specifiers do an easier job than the Cocoa formatter classes, and they can be used in the format string for the normal stringWithFormat: message to NSString.
If your requirement is to not show any trailing zeroes, then the "g" format specifier does the job:
float y = 1234.56789f;
NSString *s = [NSString stringWithFormat:#"%g", y];
Notice that there is no precision information, which means that the printf library will remove the trailing zeroes itself.
There is more information in the docs, which refer to IEEE's docs.
In case this helps someone. I wanted 1 decimal value but no '.0' on the end if the float was '1.0'. Using %g would give scientific notation for longer numbers, following ugliness worked well enough for me as high accuracy wasn't critical.
// Convert to 1 dp string,
NSString* dirtyString = [NSString stringWithFormat: #"%.1f", self.myFloat];
// Convert back to float that is now a maximum of 1 dp,
float myDirtyFloat = [dirtyString floatValue];
// Output the float subtracting the zeros the previous step attached
return [NSString stringWithFormat: #"%g", myDirtyFloat];
This will not display any decimal value after the decimal point:
display.text = [NSString stringWithFormat:#"%1.0f", trig];
This will just trim the zeros after the decimal point:
isplay.text = [NSString stringWithFormat:#"%3.2f", trig];
display.text = [display.text stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:[NSString stringWithFormat#"0"]]];
Note, this may leave you with the trailing decimal point. "124." may happen. I guess that some smarter solution will be posted soon.
From the documentation, it looks like setFractionDigits: is only for converting the other way.
The best thing to do is probably to convert your number to an integer before formatting it e.g.
double converted = round(trig); // man round for docs
You can use also the formatting functions of stringWithFormat: of NSString, but then you will lose all the localisation advantages you get with NSNumberFormatter.
This may not be a proper solution where there is NSNumberFormetter Class, But I just did this rather then googling a lot! ;)
Here is an example, if it helps:
-(NSString*) trimZerosAfterDecimalPoint:(NSString*)string_ {
double doubleValue=[string_ doubleValue];
long leftPart=(long)doubleValue;
double rightPart=doubleValue-(double)leftPart;
NSString *rightPartAsStr=[NSString stringWithFormat:#"%f", rightPart];
int i=0;
for (i=rightPartAsStr.length-1; i>=2; i--) {
if ([rightPartAsStr characterAtIndex:i]!='0') {
rightPartAsStr=[rightPartAsStr substringWithRange:NSMakeRange(2, i-1)];
break;
}
}
if (i<2) {
string_=[NSString stringWithFormat:#"%ld", leftPart];
} else {
string_=[NSString stringWithFormat:#"%ld.%#", leftPart, rightPartAsStr];
}
return string_;
}
I just had to do this for one of my programs and heres how I went about it:
- (void) simplify{
int length = (int)[self.calcString length];
for (int i = (int)[self.calcString length]; i > 0; i--) {
if ([self.calcString rangeOfString:#"."].location != NSNotFound) {
NSRange prevChar = NSMakeRange(i-1, 1);
if ([[self.calcString substringWithRange:prevChar] isEqualToString:#"0"]||
[[self.calcString substringWithRange:prevChar] isEqualToString:#"."])
length--;
else
break;
}
self.calcString = [self.calcString substringToIndex:length];
}
}
This works
display.text = [#(trig) stringValue];
it is because of your datatype cannot be formatted is such a manner.

Make a float only show two decimal places

I have the value 25.00 in a float, but when I print it on screen it is 25.0000000.
How can I display the value with only two decimal places?
It is not a matter of how the number is stored, it is a matter of how you are displaying it. When converting it to a string you must round to the desired precision, which in your case is two decimal places.
E.g.:
NSString* formattedNumber = [NSString stringWithFormat:#"%.02f", myFloat];
%.02f tells the formatter that you will be formatting a float (%f) and, that should be rounded to two places, and should be padded with 0s.
E.g.:
%f = 25.000000
%.f = 25
%.02f = 25.00
Here are few corrections-
//for 3145.559706
Swift 3
let num: CGFloat = 3145.559706
print(String(format: "%f", num)) = 3145.559706
print(String(format: "%.f", num)) = 3145
print(String(format: "%.1f", num)) = 3145.6
print(String(format: "%.2f", num)) = 3145.56
print(String(format: "%.02f", num)) = 3145.56 // which is equal to #"%.2f"
print(String(format: "%.3f", num)) = 3145.560
print(String(format: "%.03f", num)) = 3145.560 // which is equal to #"%.3f"
Obj-C
#"%f" = 3145.559706
#"%.f" = 3146
#"%.1f" = 3145.6
#"%.2f" = 3145.56
#"%.02f" = 3145.56 // which is equal to #"%.2f"
#"%.3f" = 3145.560
#"%.03f" = 3145.560 // which is equal to #"%.3f"
and so on...
You can also try using NSNumberFormatter:
NSNumberFormatter* nf = [[[NSNumberFormatter alloc] init] autorelease];
nf.positiveFormat = #"0.##";
NSString* s = [nf stringFromNumber: [NSNumber numberWithFloat: myFloat]];
You may need to also set the negative format, but I think it's smart enough to figure it out.
I made a swift extension based on above answers
extension Float {
func round(decimalPlace:Int)->Float{
let format = NSString(format: "%%.%if", decimalPlace)
let string = NSString(format: format, self)
return Float(atof(string.UTF8String))
}
}
usage:
let floatOne:Float = 3.1415926
let floatTwo:Float = 3.1425934
print(floatOne.round(2) == floatTwo.round(2))
// should be true
In Swift Language, if you want to show you need to use it in this way. To assign double value in UITextView, for example:
let result = 23.954893
resultTextView.text = NSString(format:"%.2f", result)
If you want to show in LOG like as objective-c does using NSLog(), then in Swift Language you can do this way:
println(NSString(format:"%.2f", result))
IN objective-c, if you are dealing with regular char arrays (instead of pointers to NSString) you could also use:
printf("%.02f", your_float_var);
OTOH, if what you want is to store that value on a char array you could use:
sprintf(your_char_ptr, "%.02f", your_float_var);
The problem with all the answers is that multiplying and then dividing results in precision issues because you used division. I learned this long ago from programming on a PDP8.
The way to resolve this is:
return roundf(number * 100) * .01;
Thus 15.6578 returns just 15.66 and not 15.6578999 or something unintended like that.
What level of precision you want is up to you. Just don't divide the product, multiply it by the decimal equivalent.
No funny String conversion required.
in objective -c is u want to display float value in 2 decimal number then pass argument indicating how many decimal points u want to display
e.g 0.02f will print 25.00
0.002f will print 25.000
Here's some methods to format dynamically according to a precision:
+ (NSNumber *)numberFromString:(NSString *)string
{
if (string.length) {
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
f.numberStyle = NSNumberFormatterDecimalStyle;
return [f numberFromString:string];
} else {
return nil;
}
}
+ (NSString *)stringByFormattingString:(NSString *)string toPrecision:(NSInteger)precision
{
NSNumber *numberValue = [self numberFromString:string];
if (numberValue) {
NSString *formatString = [NSString stringWithFormat:#"%%.%ldf", (long)precision];
return [NSString stringWithFormat:formatString, numberValue.floatValue];
} else {
/* return original string */
return string;
}
}
e.g.
[TSPAppDelegate stringByFormattingString:#"2.346324" toPrecision:4];
=> 2.3453
[TSPAppDelegate stringByFormattingString:#"2.346324" toPrecision:0];
=> 2
[TSPAppDelegate stringByFormattingString:#"2.346324" toPrecision:2];
=> 2.35 (round up)
Another method for Swift (without using NSString):
let percentage = 33.3333
let text = String.localizedStringWithFormat("%.02f %#", percentage, "%")
P.S. this solution is not working with CGFloat type only tested with Float & Double
Use NSNumberFormatter with maximumFractionDigits as below:
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.maximumFractionDigits = 2;
NSLog(#"%#", [formatter stringFromNumber:[NSNumber numberWithFloat:12.345]]);
And you will get 12.35
If you need to float value as well:
NSString* formattedNumber = [NSString stringWithFormat:#"%.02f", myFloat];
float floatTwoDecimalDigits = atof([formattedNumber UTF8String]);
lblMeter.text=[NSString stringWithFormat:#"%.02f",[[dic objectForKey:#"distance"] floatValue]];