conversion to doubleValue doesn't work .. but to integerValue does - objective-c

Hello all I'm trying to convert a string to a double and it doesn't work.
However if I convert it to an integer it does work
this is my code snippet
int myDuration = [myDurationString integerValue];
int conversionMinute = myDuration / 60;
if( myDuration < 60 )
{
[appDelegate.rep1 addObject:[NSString stringWithFormat:#"%d",myDuration]];
NSLog(#"show numbers %d", myDuration);
}
else
{
[appDelegate.rep1 addObject:[NSString stringWithFormat:#"%d",conversionMinute]];
NSLog(#"show numbers %d", conversionMinute);
}
Now if I try to do
double myDuration = [myDurationString doubleValue];
double conversionMinute = myDuration / 60;
then it doesn't work. It gives me an output of 0.
So the integerconversion works but somehow the double doesn't does anybody have an idea why?

You need to supply a matching format specifier. Replace every occurence of %d with %f.
%d simply fetches the next 32-bit word from the stack and treats it as a signed integer. Because of the internal representation of the floating point number, this word is zero in quite a few cases, which is why you get 0.
Here is an example that works fine for me (also with other contents of myDurationString):
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSString * myDurationString = #"19";
double myDuration = [myDurationString doubleValue];
double conversionMinute = myDuration / 60;
if( myDuration < 60 )
{
NSLog(#"show numbers %f", myDuration);
}
else
{
NSLog(#"show numbers %f", conversionMinute);
}
[pool drain];
return 0;
}

Related

How to convert long to NSString in Objective-C? [duplicate]

This question already has an answer here:
which is the correct specifier to use for long when calling stringWithFormat?
(1 answer)
Closed 2 years ago.
I try to convert long (value: 454555) to NSString. But everytime I had tried it, I got garbage value like #"-5026338884877204098".
How can I convert it same with 454555?
You can initialize a NSString by
NSString *a = #(454555).stringValue;
Here you can put all mathematical type value in the brackets,like
NSString *a = #(0.1).stringValue;//a float value
NSString *a = #(9223372036854775807).stringValue;//it's a longlong value
Try
long l = 454555;
NSString * s = [NSString stringWithFormat:#"%ld", l];
Note this is not locale aware ... but handy and sounds like the man you are looking for for your job. Here the %ld means a l=long d=decimal/int (ie long) value is next up in the parameters.
EDIT
If you like the #-way just execute the code below.
int main(int argc, const char * argv[]) {
#autoreleasepool
{
NSLog(#"Hello, World!");
for ( long i = 0; i < 1000000; i ++ )
{
// Direct ...
NSString * s = [NSString stringWithFormat:#"%ld", i ];
}
NSLog(#"1");
for ( long i = 0; i < 1000000; i ++ )
{
// Indirect via NSNumber ...
NSString * s = #(i).stringValue;
}
NSLog(#"2");
}
return 0;
}

Converting String to Character to Integer

I am trying to take a string (#"12345") and extractor each individual character and convert to it's decimal equivalent.
#"1" = 1
#"2" = 2
etc.
Here is what I have this far:
...
[self ArrayOrder:#"1234"];
...
-(void)ArrayOrder(Nsstring *)Directions
{
NSString *singleDirections = [[NSString alloc] init];
//Loop Starts Here
*singleDirection = [[Directions characterAtIndex:x] intValue];
//Loop ends here
}
I have been receiving type errors.
The problem with your code is that [Directions characterAtIndex:x] returns a unichar, which is a Unicode character.
Instead, you can use NSRange and substrings to get each number out of the string:
NSRange range;
range.length = 1;
for(int i = 0; i < Directions.length; i++) {
range.location = i;
NSString *s = [Directions substringWithRange:range];
int value = [s integerValue];
NSLog(#"value = %d", value);
}
Another approach would be to use / 10 and % 10 to get to each number from the string individually. Such as:
NSString* Directions = #"1234";
int value = [Directions intValue];
int single = 0;
while(value > 0) {
single = value % 10;
NSLog(#"value is %d", single);
value /= 10;
}
However, that goes through your string backwards.

Best way to split integers in Objective C

If I have this:
int toSplit = 208;
What's the best way to split it so I get:
2
0
8
Method would be like this
- (NSMutableArray *) toCharArray : (NSString *) str
{
NSMutableArray *characters = [[NSMutableArray alloc] initWithCapacity:[str length]];
for (int i=0; i < [str length]; i++)
{
NSString *ichar = [NSString stringWithFormat:#"%c", [str characterAtIndex:i]];
[characters addObject:ichar];
}
return characters;
}
do {
int digit = toSplit % 10;
toSplit /= 10;
printf(#"%i", digit);
} while (toSplit > 0);
I hope it's not a homework.
EDIT: it's backwards so it's not a valid answer... However, leaving it here because it can still be useful for others.
Sort it into a string then pull it apart. So like this:
int toSplit = 208;
NSString *string = [NSString stringWithFormat: #"%i", toSplit];
NSMutableString *splitApartString = [[NSMutableString alloc] init];
for (int i = 0; i < [string length]; i++) {
NSString *substring = [string substringFromIndex: i];
[splitApartString appendFormat: #"%#\n", substring];
}
NSLog(#"%#", splitApartString); //YAY!
So what this does, is puts this int into a string, splits it apart, then iterates through each character and gets a string out of that character. Then it appends that substring to a NEW string.
Another alternative, is instead of getting a substring just get the char and use the %c operator. Also if you take a look at this code you will see this output:
> 2
> 0
> 8
> // extra space here
You could just add a condition to check if i is the string length - 1 and not add a space or you could just remove the last character!
I'm not familiar with Objective-C syntax, but something like:
void split(int toSplit)
{
if (!toSplit)
{
return;
}
split(toSplit / 10);
int digit = toSplit % 10;
printf(#"%i", digit);
}

Objective C Loop

I am trying to loop this code until the yser types in DONE. I used the while loop but only parts of the embedded while loop is executed. Why is the first prompt(Enter the name) not executing in the following program? Thanks
int main (int argc, char *argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int number;
int i = 1;
double payRate, hours, totalPay;
NSString *name;
NSString *amount;
char inputBuffer[200];
NSNumberFormatter *price = [[NSNumberFormatter alloc] init];
[price setNumberStyle:NSNumberFormatterCurrencyStyle];
[price setCurrencySymbol:#"$"];
while(i > 0){
NSLog (#"Enter the name:");
scanf("%[^\n]", inputBuffer);
name = [[NSString alloc] initWithUTF8String:inputBuffer];
if([name isEqualToString:#"DONE"])
break;
else{
NSLog (#"Enter the total number of hours: ");
scanf ("%lf", &hours);
NSLog (#"Enter the pay rate: ");
scanf ("%lf", &payRate);
if(hours <= 40)
totalPay = hours * payRate;
else
totalPay = 400 + (payRate * (hours - 40) * 1.5);
NSString *myString = [NSString stringWithFormat:#"%f",totalPay];
NSNumber *myNumber = [NSNumber numberWithDouble:[myString doubleValue]];
amount = [price stringFromNumber:myNumber];
NSLog(#"Name: %#", name);
NSLog(#"Hours:%.2lf", hours);
NSLog(#"Pay Rate:%.2lf",payRate);
NSLog(#"Total Pay:%#", amount);
NSLog(#"\n");
}
}
NSLog (#"DONE!");
}
Your problem can be contributed to a number of buffering issues, such as scanf()ing numbers, but not the following line feeds. On top of this, I sometimes find that NSLog() messes of stdin/stdout buffering if you are also using printf() or scanf(). Usually I find it best to avoid the scanf() function whenever possible, especially when using a higher-level language like Objective-C.
Instead of using scanf() to read user input, I wrote a small function to read a line from the console, and return it as an NSString. This function looks as follows:
NSString * readLine (FILE * input) {
NSMutableString * string = [[NSMutableString alloc] init];
int aChar = 0;
while ((aChar = fgetc(input)) != EOF) {
if (aChar != '\r') {
if (aChar == '\n') {
break;
} else if (aChar > 0) {
[string appendFormat:#"%C", aChar];
}
}
}
return [string autorelease];
}
Using this, you could rewrite your main() function using this new method. In the following code I have also taken out all NSLog() statements that prompt the user for information, replacing them with more appropriate printf() calls.
int main (int argc, char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
double payRate, hours, totalPay;
NSString * name;
NSString * amount;
NSNumberFormatter * price = [[NSNumberFormatter alloc] init];
[price setNumberStyle:NSNumberFormatterCurrencyStyle];
[price setCurrencySymbol:#"$"];
while (YES) {
printf("Please, enter your name: ");
name = readLine(stdin);
if ([name isEqualToString:#"DONE"])
break;
else {
printf("Enter the total number of hours: ");
hours = [readLine(stdin) intValue];
printf("Enter the pay rate: ");
payRate = [readLine(stdin) intValue];
if (hours <= 40)
totalPay = hours * payRate;
else
totalPay = 400 + (payRate * (hours - 40) * 1.5);
NSNumber * myNumber = [NSNumber numberWithDouble:totalPay];
amount = [price stringFromNumber:myNumber];
NSLog(#"Name: %#", name);
NSLog(#"Hours: %.2lf", hours);
NSLog(#"Pay Rate: %.2lf",payRate);
NSLog(#"Total Pay: %#", amount);
}
}
[price release];
NSLog(#"DONE!");
[pool drain];
}
In: scanf("%[^\n]", inputBuffer); that does not read anything from the user, you need to read from the user into inputBuffer.
Also NSLog is not a good way to send text to the user, probably use "C" functions since you are writing a "C" program.

File output as .csv objective C

Hello guys I'm writing a test file for a program. where all the possible numbers are tested and i want the result to be logged as a .csv file,so i can upload it into excel.
float calc (float i, float j , float p, float ex){
float nodalatio = (p/ex);
float ans = (0.68 *j + 1.22*nodalatio + 0.34*j -0.81);
return ans;
}
int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
float stage , grade, pos, ex;
float resul;
for (int i=1;i<=3;i++){
stage = i;
for(int j=1;j<=3;j++){
grade = j;
for(int p=1;p<=60;p++){
pos = p;
for(int e=1;e<=60;e++){
ex=e;
resul = calc(stage, grade,pos,ex);
NSLog(#"stage is %f grade is %f,pos is %f ex is %f the result is %f",stage,grade,pos,ex,resul);
}
}
}
}
[pool drain];
return 0;
}
the above is the test code and i can't seem to figure how to output this in to a .csv file. does the code in the loop or after the loop. this is what i had but this did nothing !
NSString *file_path = #"test.csv";
NSString *test_1 = [NSString stringwithformat#"%f",resu];
[test_1 writeToFile:file_path atomically:YES encoding:NSUnicodeStringEncoding error:nil];
thank you
Try this:
float calc(float, float, float, float);
float calc (float i, float j , float p, float ex)
{
float nodalratio = (p / ex);
float ans = (0.68 * j + 1.22 * nodalratio + 0.34 * j - 0.81);
return ans;
}
int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
float stage , grade, pos, ex;
float resul;
[[NSFileManager defaultManager] createFileAtPath: #"test.csv" contents: [#"" dataUsingEncoding: NSUnicodeStringEncoding] attributes: nil];
NSFileHandle *file = [NSFileHandle fileHandleForWritingAtPath: #"test.csv"];
[file seekToEndOfFile];
for (int i = 1; i <= 3; i++)
{
stage = i;
for(int j = 1; j <= 3; j++)
{
grade = j;
for(int p = 1; p <= 60; p++)
{
pos = p;
for(int e = 1; e <= 60; e++)
{
ex = e;
resul = calc(stage, grade, pos, ex);
NSString *str = [NSString stringWithFormat: #"%f, %f, %f, %f, %f\n", stage, grade, pos, ex, resul];
[file writeData: [str dataUsingEncoding: NSUTF16LittleEndianStringEncoding]];
}
}
}
}
[file closeFile];
[pool drain];
return 0;
}
That works for me. It will contain a proper BOM and write each string in UTF-16 (Unicode). Using other encodings, like NSUTF16StringEncoding, will write a BOM for each line, which is not really what you want.
FWIW, are you sure it is not 0.68 * j and 0.34 * i or vice versa?
Don't reinvent the wheel:
http://github.com/davedelong/CHCSVParser
My CSV parser class also includes a CSV writer for creating CSV files.