jpo
jpo

Reputation: 4059

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!");

   }

Upvotes: 1

Views: 316

Answers (2)

Alex Nichol
Alex Nichol

Reputation: 7510

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];
}

Upvotes: 2

zaph
zaph

Reputation: 112857

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.

Upvotes: 1

Related Questions