# C++ and atoi()



## mussavcom (Mar 29, 2004)

If you're familiar with the atoi() function (ASCII to integer), maybe you can help me.

Why doesn't this work?


```
#include <iostream>
using namespace std;
#include <cstdlib>

int main()
{
    char *useoldmoneyC;
    cout << "1 or 2? ";
    cin >> useoldmoneyC;
    cout << useoldmoneyC;
    int useoldmoney = atoi(useoldmoneyC);
    // above makes sure while loop below doesn't go crazy
    // if a letter is entered
    while (useoldmoney != '1' && useoldmoney != '2')
    {
        cout << "Please enter 1 to resume your game or 2 to start over: ";
        cin >> useoldmoneyC;
        useoldmoney = atoi(useoldmoneyC);
    }

    return 0;
}
```
When I run this, it outputs "1 or 2? " and then crashes. The console window stays open, but a popup says "filename.exe has encountered a problem and needs to close. We are sorry for the inconvenience.
If you were in the middle of something, the information you were working on might be lost.

Please tell Microsoft about this problem.
We have created an error report that you can send to us. We will tread this report as confidential and anonymous.

To see what data this error report contains, click here."
Then there are 3 buttons:
Debug, Send Error Report, and Don't Send.
Regardless of what I click, the window pops up two more times. Then, the console window closes.


----------



## AlbertB (Nov 24, 2002)

You seem to have declared a char pointer rather than just a char on your line:

char *useoldmoneyC;

Take out the * !

If you try inputting values into this I am not surprised you are getting corruption and error messages .


----------



## coderitr (Oct 12, 2003)

I recommend using _getche( ) to input the number rather than cin. If the user enters more than one character before pressing enter, you will overwrite whatever is in the memory adjacent to the char which *will* cause problems which *may* be manifest by a program crash or nothing at all. Since _getche( ) will echo the character to the screen and return after the first character is typed, it's more safe.

You could also make your char a char[8] which would accommodate up to 8 characters but you still have the same problem there: what if I enter 9 digits? The atoi( ) will still work with a char array.

Depending on your compiler the definition of _getche( ) may be simply getche( ).


----------



## mussavcom (Mar 29, 2004)

Thanks... I'll try taking out the *.

I'm not to good with char's. I'm having trouble with this code now:


```
#include <iostream>
using namespace std;
#include <dos>

int getChoice(int, char[], char[4][100] );
int Window();
int Door();
int main()
{

    // a bunch of cout's, and then:
    char routes[2][100] = {{"Jump out the window?"},{"Run out the classroom door?"}};
    int choice = getChoice(2,"Do you: ",routes);

    system("cls");
    int send1;
    if (choice == 1)
        send1 = Window();
    else
        send1 = Door();

    system("cls");
    switch(send1)
    {
        case 1:
            cout << "You run towards the parking lot...";
            break;
        case 2:
            cout << "You run towards the bus loop...";
            break;
    }
    cout << "\n\n\n";
    system("pause");
    return 0;
}

int getChoice(int numChoices, char msg[], char routes[4][100])
{
    cout << "\n\n " << msg;
        sleep(1);
    for ( int j = 0; j < numChoices; j++ )
    {
        cout << "\n    " << j + 1 << ". " << routes[j];
        sleep(1);
    }
        cout << "\n Type the number of your choice and hit Enter. ";
        int choice;
        char *choiceC;
        cin >> choiceC;
        choice = atoi(choiceC);
        while (choice != 1 && choice != 2)
        {
            cout << "\nPlease enter either 1 or 2. ";
            cin >> choiceC;
            choice = atoi(choiceC);
        }
	return choice;
}
int Window()
{
    // bunch of cout's depicting a story....
    char routes[2][100] = {{"Run to the front parking lot?"},{"Sprint to the bus loop?"}};
    return getChoice(2,"You are now at the front of the school. Do you: ",routes);

}

int Door()
{
    //more cout's

    char routes[2][100] = {{"Run to the front parking lot?"},{"Sprint to the bus loop?"}};
    return getChoice(2,"You are finally outside the school. Do you: ",routes);

}
```
When I run it, it displays the first choice (in main() ) correctly:

Do you:
1. Jump out the window?
2. Run out the classroom door?
Type the number of your choice and hit Enter.

If I type in 2 and hit Enter, it again works fine:
You are finally outside the school. Do you: 
1. Run to the front parking lot? 
2. Sprint to the bus loop?
Type the number of your choice and hit Enter.

But if I type in 1 at the beginning instead, it doesn't work:
You are now at the front of the school. Do you: 
1. 1
2. Sprint to the bus loop?
Type the number of your choice and hit Enter.

Why does it display a 1 instead of displaying "Run to the front parking lot?" like it should?


----------



## mussavcom (Mar 29, 2004)

About the problem above..

I've been working on it and have figured out that if I switch the Door() function and the Window() function (that is, cut the entire Door() function and paste it _above[/ii] the Window() function), then the function on top--now Door()--will be the function that messes up by displaying the number 1 as the first choice.

Another thing... if I change the if statement in function main() from
if (choice == 1)
to 
if (choice != 1)

then where it messes up by displaying
1. 1
it will instead display
1. 2_


----------



## mussavcom (Mar 29, 2004)

> You seem to have declared a char pointer rather than just a char on your line:
> 
> char *useoldmoneyC;
> 
> Take out the * !


Then I get the error:
Errer E2285 casino.cpp 58: Could not find a match for 'atoi(char)' in function main()


----------



## AlbertB (Nov 24, 2002)

I just changed your code to this:

int choice = 0;
char invar = '0';
cin >> invar;
choice = atoi(&invar);
while (choice != 1 && choice != 2)
{
cout << "\nPlease enter either 1 or 2. ";
cin >> invar;
choice = atoi(&invar);
}
return choice;

it's primitive but it now works perfectly.  It has a new char variable declared, 'invar', a char which can thus be used in cin to accept '1' or '2'. I then pass the *address* of this selection, ie the address *&*invar, to atoi(*char), legal as it expects a char pointer which of course contains an address to a char as does &invar. Voila! 

I think you have a confusion between chars and char pointers again. atoi(*char) requires to be passed a pointer to a char which is what you were originally doing correctly, cin requires to read from a byte stream, that is it pulls in bytes not addresses. Your choiceC was declared as a pointer and thus was invalid to use in cin.


----------



## mussavcom (Mar 29, 2004)

Thanks again! I really need to stop jumping ahead of myself... kind of hard with this boring c++ book 

So the cin-ing to a pointer to a char is what was causing the error? It's weird that it only has an error on the function closest to main().... *shrug*

Thanks!


----------



## mussavcom (Mar 29, 2004)

hmm... Now if you enter, say, "one" instead of 1, it will say "Please enter 1 or 2: " 3 times. Should I use cin.getline() or something instead of cin?


----------



## AlbertB (Nov 24, 2002)

Now you're expanding your ideas. That is what I think coderitr suggested in another thread. Explore the alternative ways of inputting your data. cin is a starting point but other methods of input are easier to provide verification checks on, and as we said before, if a user can do something utterly stupid - they will! That makes programming bomb proof and hence professional.

If you are wanting to take your C/C++ programming to a good level pointers and addresses are something you must master, they are so versatile and powerful.

Using getline() is one option and it would be useful to you to get it working. That will input a char string into a buffer and terminate its input with a return '\n' character. The trouble with that approach is that it allows more than one character to be input, a line in fact, and requires a <return> to be entered by the user. It can be done but will still have limitations.

Have a look at _getch() and _getche(). You will need to "#include <conio.h>" to use these two functions. They both wait for a key press and return immediately with the value of the key.

eg

int choice;
char ch;
ch = _getch(); // waits for a key to be pressed and returns the value of that key into ch
choice = atoi(&ch); // passes the *address* of ch into atoi() which returns the numerical value of the content of ch to choice

Now one thing to consider here is that _getch() does not echo (or display) the value input to the screen, so if you need to do that you must arrange it yourself. Or you could just use _getche() because that *does* echo the value to the screen.

You must find out if your compiler supports these functions as _getch() or just getch(), it varies. M$ VisC++ 6.0 uses _getch() but I believe Borland for example recognises getch(). Just type it one way and see if it throws up an error.

Good luck.


----------



## mussavcom (Mar 29, 2004)

Wow, thanks again for all your help. I'm using Borland, and it's getch().
Since my program clears the screen once the number is input, it didn't matter to me that getch() doesn't echo the keypress. But then I decided to use getche(), sleep for 1 second, and then clear the screen, since it just seems more professional.

Now at the beginning of my program, I used system("COLOR 70"); to set the colors of the console window to gray background, black text, since some defaults are much harder to read. When I use getche(), however, it displays that number in the default color setting (mine is blue background with white text). I put in another system("COLOR 70") right after the getche() function, and that seemed to work (although sometimes it flashes the number in the default colors right before switching). 

I'll decide if I want to use the color setting on the getche() or not... it might be better to have the choice stand out for the 1 second it's on the screen, who knows, and I won't have to worry about the weird flash. I'll play around with it. 

Anyway, thanks again for your help!


----------

