开发者

Creating a Basic Print Calculator in Objective-C Using a Nested Switch in a While Loop

I am currently a sophomore Computer Scientist in college and all I've learnt so far in terms of programming is very basic Python and Java and that's really it. Since I own a Mac, I decided to try and practice Objective-C and bought a book off of Amazon to help me along the way (the book is Programming in Objective-C, Third Edition by Stephen G. Kochan. Its an excellent book for me since I'm still new to programming in general!)

One of the exercises that my book recommends for me to do is creating a simple print calculator using the switch statements and boolean variables I learnt in the previous chapter. The program is designed to execute as shown below:

Welcome to PrintCalc! Available functions are +, -, *, /, S, and E. Type in the form of [integer] [operator].

My input: 100 S

Feedback: = 100

My input: 50 +

Feedback: = 150

My input: 2 /

Feedback: = 75

My input: 0 E

Feedback: = 75

Then the program should terminate.

The S operator will set the accumulator which is defined in the @interface and @implementation sections of my program. The E operator will always take 0 as the numerical input but the number doesn't really matter. E simply terminates the program.

Here is the code for my program. I'm going to only show the main method here and the @ implementation section later, but if you would like to see the @interface section then I will gladly. Also, you might want to disregard some of my comments since a lot of them probably won't make much sense!

int main (int argc, char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc]init];

//Define the variables to be used in the outermost scope of the program.
double thisNum;
char thisChar;
BOOL isFinished;
PrintCalc * CalcInstant = [[PrintCalc alloc]init];

NSLog(@"\nWelcome to PrintCalc! Available functions are +, -, *, /, S, and E. \nType in    the form of [integer] [operator].");

//Initialize the isFinished variable.
isFinished = false;

//This do-while loop should terminate with the falsification of the isFinished boolean.
do
{
    scanf (" %f %c", &thisNum, &thisChar);
    //Use a 'switch' statement to make multiple decisions and meet multiple conditions.
    switch (thisChar)
    {
        case 'S':
            [CalcInstant setAccumulator: thisNum];
            NSLog(@"= %f", [CalcInstant accumulator]);
            break;

        case '+':
            [CalcInstant add: thisNum];
            NSLog(@"= %f", [CalcInstant accumulator]);
            break;

        case '-':
            [CalcInstant subtract: thisNum];
            NSLog(@"= %f", [CalcInstant accumulator]);
            break;

        case '*':
            [CalcInstant multiply: thisNum];
            NSLog(@"= %f", [CalcInstant accumulator]);
            break;

        case '/':
            [CalcInstant divide: thisNum];
            NSLog(@"= %f", [CalcInstant accumulator]);
            break;

        case 'E':
            isFinished = true;
            break;

        //This next case is a 'hidden' operator that only the programmer knows about. Displays the value of the thisNum variable.
        case '@':
            NSLog(@">>> %f", thisNum);
            break;

        default:
            NSLog(@"Bad operator and/or not a real number.");
            break;
    }
}
while (isFinished != true);

NSLog(@"= %g", [CalcInstant accumulator]);

[CalcInstant release];
[pool drain];

return 0;
}

There exists two problems with my program (that I know of...). First of all, the program originally contained a while loop rather than a do-while loop. For some strange reason, the do-while loop works perfectly, whereas if I used a while loop, the program would never enter the loop. Does anybody know why this would occur?

My second problem is the computer does not seem to recognize the variable thisNum. The reason I created the '@' operator in the switch statement was to test to see if the computer would read in the number provided. For some odd reason it doesn't, although my code in the @implementation section seems to work fine if I 'hard code' the operations into the program itself rather than use user input to ask what operation should be performed. (Ex: I simply type [CalcInstant add: 50] to make the computer add 50 to the accumulator.) Here is the @implementation section.

@implementation PrintCalc

-(void) setAccumulator: (double) value
{
    accumulator = value;
}

-(double) accumulator
{
    return accumulator;
}

-(void) add: (double) value
{
    accumulator += value;
}

-(void) subtract: (double) value
{
    accumulator -= value;
}

-(void) multiply: (double) value
{
    accumulator *= value;
}

-(void) divide: (double) value
{
    accumulator /= value;
}

@end

The program will start and terminate normally, even with the use of the 'E' operator, which means that the operators are reading in just fine. However, when I use my special '@' operator with the value 100, the computer returns '0.000000' as the value o开发者_JS百科f thisNum, which is incorrect.

This may very well be a beginner's mistake but I am learning! Please don't be too harsh on me but constructive criticism is always welcome! Thank you so much for any help you can provide!


This is a very common problem when using the scanf function and doubles. Infact, if you google those two search terms you will get a surprisingly long list of hits with people having the same issue. Basically, you want to use the %lf format specifier to read doubles using scanf, not just %f. I changed that and tested your code and it works very well.

I also moved the while statement back to the top of your loop and it works fine. I suspect you made some other changes between when you first had that issue and now, because everything functions as expected.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜