简体   繁体   English

我的程序中的无限循环

[英]Infinite loop in my program

Ok, so for my school project we are basically making a menu with 20 max people to enter information and change if need be.好的,所以对于我的学校项目,我们基本上制作了一个最多 20 人的菜单,可以输入信息并在需要时进行更改。 Everything was working fine.一切正常。 However, our assignment has us check input for zip code and Account Balance for integer values.然而,我们的任务让我们检查邮政编码的输入和整数值的帐户余额。 I used a do-while loop for ZipCode validation until a positive number and a digit was entered.我使用 do-while 循环进行 ZipCode 验证,直到输入一个正数和一个数字。 However, I get an infinite loop that I can't seem to fix.但是,我得到了一个似乎无法修复的无限循环。 Here is my code.这是我的代码。 The error lies on lines 57-68 if you put into a compiler.如果放入编译器,则错误位于第 57-68 行。 Every time I enter a letter instead of a integer, I get an infinite loop.每次我输入一个字母而不是一个整数时,我都会得到一个无限循环。 But I can't figure out why.但我想不通为什么。 Thanks!谢谢!

#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>

using namespace std;

struct Account //Structure to be used throughout
{
     string CustomerName; 
     string CustomerAddress;
     string City;
     string State;
     int ZIPCode;
     string Telephone;
     int AccountBalance;
     string DateOfLastPayment;

};



//function prototypes 
void valueChangeFunc(string, Account[], int);//This function will be used in option 2 for editing a certain customer information



int main()
{
    Account array[20]; //Array to hold up to 20 customers 
    int choice;  //this will hold which option the user decides to make 1-4
    bool flagZip = false; //This will be used later on as a flag for a do-while loop
    bool flag = false; //This will be used as a flag for the do-while loop right now
    int index = 0; //Index for our customers. This tells how many customers have been entered
    do //This do while loop will continue to ask the user what option to do until array fills up with 20 people and 4 is not entered
    {
    cout << "1. Enter new account information \n" <<endl 
     << "2. Change account information \n" << endl
     << "3. Display all account information\n" <<endl
     << "4. Exit the program \n" <<endl;
     cin >> choice; 
if (choice > 4 || choice <= 0)//If user enters a number bigger than 4 or less then or equal to 0. Error! 
cout << "Please enter a number between 1 and 4" << endl;

else if(choice == 1)
{
cout << "CustomerName: ";
        cin.ignore();
    getline(cin, array[index].CustomerName);
    cout << "CustomerAddress ";
    getline(cin, array[index].CustomerAddress);
    cout << "City: ";
    getline(cin, array[index].City);
    cout << "State: ";
    getline(cin, array[index].State);

    do
    {
    cout << "Zip Code: ";
    cin >> array[index].ZIPCode;
    cin.ignore();
    if (!isdigit(array[index].ZIPCode) && array[index].ZIPCode <= 0)
    cout << "Please enter a valid entry " << endl;

    else 
    flagZip = true;

    }while(flagZip == false);

    cout << "Telephone: ";
    getline(cin, array[index].Telephone);

    flagZip = false;

    do 
    {
    cout << "AccountBalance: ";
    cin >> array[index].AccountBalance;
    cin.ignore();
    if (array[index].AccountBalance <= 0)
    cout << "Please enter a valid entry " << endl;

    else
    flagZip = true;
    }while(flagZip == false); 

    cout << "DateOfLastPayment: ";
    getline(cin, array[index].DateOfLastPayment);


    cout << "\n\nCustomerName: " << array[index].CustomerName << endl;
    cout << "CustomerAddress " << array[index].CustomerAddress <<endl;
    cout << "City: " << array[index].City << endl;
    cout << "State: " << array[index].State << endl;
    cout << "Zip Code: " << array[index].ZIPCode << endl;
    cout << "Telephone: " << array[index].Telephone <<endl;
    cout << "AccountBalance: " << array[index].AccountBalance << endl;
    cout << "DateOfLastPayment: " << array[index].DateOfLastPayment << endl;
    cout << "You have entered information for customer number " << index << endl << endl;

    index++;
}
else if(choice == 2 && index != 0)
{
int num;
string valueChange;
do
{
cout << "  Customer number: ";
cin >> num;

if (num > (index-1) || num < 0)
cout << " There is no customer with that number " << endl;

}while (num > (index-1));
    cout << "\n\nCustomer Name: " << array[num].CustomerName << endl;
    cout << "Customer Address " << array[num].CustomerAddress <<endl;
    cout << "City: " << array[num].City << endl;
    cout << "State: " << array[num].State << endl;
    cout << "ZIPCode: " << array[num].ZIPCode << endl;
    cout << "Telephone: " << array[num].Telephone <<endl;
    cout << "Account Balance: " << array[num].AccountBalance << endl;
    cout << "Date of last payment: " << array[num].DateOfLastPayment << endl;
    cout << "You have requested information for customer number " << num << endl << endl;

    cout << "What value do you want to change? (press 4 to change 'Date of last payment') \n"; 
    cin.ignore();
    getline(cin,valueChange);

    valueChangeFunc(valueChange, array, num);

    cout << "\nHere is the new value you entered for " << valueChange << endl;

    cout << "\n\nCustomer Name: " << array[num].CustomerName << endl;
    cout << "Customer Address " << array[num].CustomerAddress <<endl;
    cout << "City: " << array[num].City << endl;
    cout << "State: " << array[num].State << endl;
    cout << "ZIPCode: " << array[num].ZIPCode << endl;
    cout << "Telephone: " << array[num].Telephone <<endl;
    cout << "Account Balance: " << array[num].AccountBalance << endl;
    cout << "Date of last payment: " << array[num].DateOfLastPayment << endl << endl;

}

else if(choice == 3 && index != 0)
{
    int num2;
do
{
    cout << "Enter the Customer Number to display information regarding that customer" << endl;
    cin >> num2; 
if (num2 > (index-1) || num2 < 0)
cout << "That Customer does not exist " <<endl; 
}
while(num2 > (index-1));


    cout << "\n\nCustomerName: " << array[num2].CustomerName << endl;
    cout << "CustomerAddress " << array[num2].CustomerAddress <<endl;
    cout << "City: " << array[num2].City << endl;
    cout << "State: " << array[num2].State << endl;
    cout << "Zip Code: " << array[num2].ZIPCode << endl;
    cout << "Telephone: " << array[num2].Telephone <<endl;
    cout << "AccountBalance: " << array[num2].AccountBalance << endl;
    cout << "DateOfLastPayment: " << array[num2].DateOfLastPayment << endl;
    cout << "You have entered information for customer number " << index << endl << endl;

}

else 
flag = true;

}while (flag == false);

    return 0;
}

void valueChangeFunc(string valueChange2, Account array[], int num)
{
    if (valueChange2 == "Customer Name" || valueChange2 == "Customer name" || valueChange2 == "customer Name" || valueChange2 == "customer name")
    {
    cout << "\nEnter new value for Customer Name: " <<endl;
    getline(cin, array[num].CustomerName);

    }

    if (valueChange2 == "Customer Address" || valueChange2 == "Customer address" || valueChange2 == "customer Address" || valueChange2 == "customer address")
    {
    cout << "\nEnter new value for Customer Address: " <<endl;
    getline(cin, array[num].CustomerAddress);

    }
    else if(valueChange2 == "city" || valueChange2 == "City")
    {
        cout << "\nEnter new value for City: " << endl;
        getline(cin, array[num].City);

    }
    else if(valueChange2 == "state" || valueChange2 == "State")
    {
        cout << "Enter a value for State: " << endl;
        getline(cin,array[num].State);

    }

    else if(valueChange2 == "Zip Code" || valueChange2 == "zip Code" || valueChange2 == "Zip code" || valueChange2 == "zip code")
    {
        cout << "\nEnter a value for Zip Code: " << endl;
        cin >> array[num].ZIPCode;

    } 

    else if(valueChange2 == "telephone" || valueChange2 == "Telephone")
    {
        cout << "\nEnter a value for Telephone: " << endl;
        getline(cin, array[num].Telephone);

    }

    else if(valueChange2 == "Account Balance" || valueChange2 == "Account balance" || valueChange2 == "account Balance" || valueChange2 == "account balance")
    {
        cout << "\nEnter a value for account balance: " << endl;
        cin >> array[num].AccountBalance;

    }
    else if(valueChange2 == "4")
    {
        cout << "\nEnter the value for Date of last payment: " << endl;
        getline(cin, array[num].DateOfLastPayment);

    }

    else 
    cout << "Not entered correctly. Please enter a valid entry to edit " << endl;

}

Again everything worked until I started to use a loop to check for digit value of ZipCode.一切正常,直到我开始使用循环来检查 ZipCode 的数字值。 The loop only goes infinite when I enter a letter.当我输入一个字母时,循环只会无限循环。 It works for a negative number and positive number.它适用于负数和正数。

Short answer can be found in cplusplus.com (read the third paragraph)简答可在 cplusplus.com 中找到(阅读第三段)

Long answer:长答案:

This error isn't about ZipCode only, you can generate the same error when you input a letter instead of a number at the very first cin call.此错误不仅仅与 ZipCode 有关,当您在第一次调用cin时输入字母而不是数字时,您可能会生成相同的错误。

cin is not type-safe so using a wrong type as an input results in an undefined behaviour (like the infinite loop you were experiencing) and that is why cin is a bit prone to errors. cin不是类型安全的,因此使用错误的类型作为输入会导致未定义的行为(例如您遇到的无限循环),这就是为什么cin有点容易出错的原因。 Also, cin gets the input value, however it doesn't remove newline, reading to a bit dirtier input from what you'd get with other methods.此外, cin获取输入值,但它不会删除换行符,而是从其他方法获得的内容中读取更脏的输入。

Speaking of other methods, as explained in the link, try to use getline() whenever it is possible.说到其他方法,如链接中所述,尽可能尝试使用getline() You can use that function to get what cin buffer contains as a string and do additional type-check if necessary.您可以使用该函数来获取cin缓冲区包含的字符串,并在必要时进行额外的类型检查。 Bug-free programs are more important than shorter programs.无错误程序比较短的程序更重要。

As a personal note: try to use while loops instead of do..while ones when you can.作为个人说明:尽可能使用while循环而不是do..while循环。 That is not a general rule of programming but it looks more readable and is easier to understand in general (IMHO).这不是编程的一般规则,但它看起来更具可读性并且更容易理解(恕我直言)。

Also, try to use functions to split your program into parts.此外,尝试使用函数将您的程序拆分为多个部分。 For example, the cout blocks where you are just printing the information stored to the screen can be turned into a function.例如,您只是打印存储到屏幕上的信息的cout块可以变成一个函数。 You're using the same cout structure (it would shorten your code by 4 * 9 lines).您使用的是相同的cout结构(它会将您的代码缩短 4 * 9 行)。

Finally, if you're using an integer as a key value to separate algorithms, try to use switch...case instead of if-else blocks.最后,如果您使用整数作为键值来分隔算法,请尝试使用switch...case而不是if-else块。 (Again, just my opinion). (再次,只是我的意见)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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