C ++ Primer Plus第6章练习2输入理解

时间:2015-02-11 10:15:15

标签: c++

我正在学习C ++ Primer Plus书,我最近从书中完成了这个练习。我有一个问题:当用户点击输入时没有任何符号,然后在下一个条目中显示任何这些功能,他必须再次输入,因为如果不是它仍然会显示"错误的选择&#34 ; "下一个选择:"每时每刻。你能告诉我这段代码有什么问题,我应该添加什么? 提前谢谢。

        /*When you join the Benevolent Order of Programmers, you can be known at BOP
    meetings by your real name, your job title, or your secret BOP name.Write a program
    that can list members by real name, by job title, by secret name, or by a member’s
    preference. Base the program on the following structure:
    // Benevolent Order of Programmers name structure
    struct bop {
    char fullname[strsize]; // real name
    char title[strsize]; // job title
    char bopname[strsize]; // secret BOP name
    int preference; // 0 = fullname, 1 = title, 2 = bopname
    };
    In the program, create a small array of such structures and initialize it to suitable
    values. Have the program run a loop that lets the user select from different alternatives:
    a. display by name b. display by title
    c. display by bopname d. display by preference
    q. quit
    302 Chapter 6 Branching Statements and Logical Operators
    Note that “display by preference” does not mean display the preference member; it
    means display the member corresponding to the preference number. For instance, if
    preference is 1, choice d would display the programmer’s job title.A sample run
    may look something like the following:
    Benevolent Order of Programmers Report
    a. display by name b. display by title
    c. display by bopname d. display by preference
    q. quit
    Enter your choice: a
    Wimp Macho
    Raki Rhodes
    Celia Laiter
    Hoppy Hipman
    Pat Hand
    Next choice: d
    Wimp Macho
    Junior Programmer
    MIPS
    Analyst Trainee
    LOOPY
    Next choice: q
    Bye!*/

解决方案:

    #include <iostream>

    void text();
    void name();
    void title();
    void secret();
    void prefr();

    const int strSize = 23;
    const int People = 4;

    char ch;

    struct bop {
    char fullname[strSize]; // real name
    char title[strSize];    // job title
    char bopname[strSize];  //secret BOP name
    int preference;         // 0 = fullname, 1 = title, 2 = bopname
    };

    bop people[People]  //array of 4 structures
        {
            {"Tony Hawk", "Junior Programmer", "Novice",2},  //first member
            {"Bill Gates", "Founder of Microsoft", "Billionaire",1},    //second member
            {"Pop Leather", "Graphic Designer", "Fast and Furious",2},  //third member
            {"Steve Jobs", "Apple Leader", "Undead Dragon",0}   //fourth member
        };


    int main()
    {
        text();    //call a text function
        std::cin.get(ch);    //get a character
        int i=0;
        while(ch!='q')
        {
            switch(ch)
            {
                case 'a':
                    name();
                    break;
                case 'b':
                    title();
                    break;
                case 'c':
                    secret();
                    break;
                case 'd':
                    prefr();
                    break;
                default: std::cout << "Wrong choice\n";
            }

            std::cout << "Next choice: \n";
            std::cin.get();
            std::cin.get(ch);
        }
        std::cout<<"Bye!";
        return 0;
    }

    void text()
    {
        std::cout<<"Benevolent Order of Programmers Report\n"
        "a. display by name         b. display by title\n"
        "c. display by bopname      d. display by preference\n"
        "q. quit\n"
        "Enter your choice:";
    }   
    void name()
    {
        for(int i=0;i<People;i++)
        std::cout<<people[i].fullname<<std::endl;
    }
    void title()
    {
        for(int i=0;i<People;i++)
        std::cout<<people[i].title<<std::endl;
    }
    void secret()
    {
        for(int i=0;i<People;i++)
            std::cout<<people[i].bopname<<std::endl;
    }
    void prefr()
    {
        for(int i=0;i<People;i++)
        {
            if(people[i].preference==0)
                std::cout<<people[i].fullname<<std::endl;
            else if(people[i].preference==1)
                std::cout<<people[i].title<<std::endl;
            else if(people[i].preference==2)
                std::cout<<people[i].bopname<<std::endl;
        }
    }

1 个答案:

答案 0 :(得分:0)

我认为问题在于:

std::cin.get();
std::cin.get(ch);

如果确实存在某个字符,则第一个get将清除换行符,第二个将执行另一个读取。

如果没有字符开头,则第一个get会消耗实际输入,ch最终会作为换行符。


解决方案是:如果您不确定输入是否有效,请不要将输入视为有效。特别是,你期望输入两个字符:除换行后跟换行符之外的任何字符。

有两种简单的方法可以解决您的问题:

  • 不要使用字符:只需处理std::string并将空字符串视为无效。
  • 检查第一个字符是否为换行符,然后跳过其他字符。

更高级的解决方案是尝试更多功能。你可以将输入包装回来optional<char>吗?或者甚至更好,optional<Choice>,其中Choiceenum class

或许您可以创建一个自动循环的函数,每次都提示输入正确的输入,并将其与主程序逻辑分开?