简体   繁体   中英

Why does this code involving cin skip getline even with cin.ignore()?

The following code works as intended for the first two getlines and after you input the CC variable it goes into an infinite loop skipping the getlines and not waiting for input.

Here is a sample run:

Enter card holder name (or quit): John Doe

Enter CC number: 1234 1234 1234 1555

// code outputs the other couts but does not wait for input of getline. and reiterates the cout statements. cin.ignore does not seem to help or cin.clear()

Code:

 int main(int argc, char* argv[]) {

    char CCName[64];    //cardholder name
    char  CCNumber[16]; //credit card number
    char Expiration[8]; //expiration date 
    float Amount;     


    while (true) {

        /* input processing block */

        //gather card holder name
        cout << "\nEnter card holder name (or quit): ";
        cin.getline(CCName, 64);

        //quit command processing 
        if (strcmp(CCName, "quit") == 1) {
            cout << "\nYou successfully terminated the program\n";
            //~ close(sockfd); //close socket
            exit(EXIT_SUCCESS);
        }

        //gather credit card number
        cout << "\nEnter CC number: ";
        cin.getline(CCNumber, 16);
        //error checking
        if (strlen(CCNumber) != 15 && strlen(CCNumber) != 16) {
            cout << "\nCredit card number must be 15 to 16 digits, try again: ";
            cin.getline(CCNumber,16);
        } 

        //gather expiration date
        cout << "\nEnter expiration: ";
        cin.ignore();
        cin.getline(Expiration, 7);
        //error checking
        if (strlen(Expiration) != 7) {
            cout << "\nExpiration date format mm/yyyy. Try again: ";
            cin.getline(Expiration, 7);
        }

        //gather amount
        cout << "\nEnter amount: ";
        cin >> Amount;
}

   return 0;
}

Using cin.getline() is very dangerous to use. cin.getline() reads the input from the keyboard then when it reads the newline(generated when the user pressed the enter key), it replaces the newline with a null character . See how this would cause an error? Even more, you need to worry about the size of the input, and this just puts too much restriction, making it less user friendly. I would recommend using getline(cin,stringName) instead.

I have some suggestions on the code, 1. Increase the size of the char array

char CCName[65];    //cardholder name
char  CCNumber[17]; //credit card number

2. Correct the if condition

if (strcmp(CCName, "quit") == 0) {

3. Change this

if (strlen(CCNumber) != 15 && strlen(CCNumber) != 16) {

by this

while (strlen(CCNumber) != 15 && strlen(CCNumber) != 16) {

4. About the date input, you could write a separate function to check its validality.

Your problem is your giving it more characters than CCNumber can hold

when you do

1234 1234 1234 1555 

as your input it is in fact 19 characters (the spaces count) not 16 this leaves extra characters in cin which is causing the weird behavior. I modified it to do be

    cout << "\nEnter CC number: ";
    cin.ignore();
    cin.getline(CCNumber, 16);

with input

1234123412341234

and that part worked. if you want the spaces increase the size of the array. Also as has been pointed out this is not very safe because you are assuming the user is going to give you perfect data. A very dangerous assumption.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM