在 C++ 中不允许相同的输入 [关闭]

Posted

技术标签:

【中文标题】在 C++ 中不允许相同的输入 [关闭]【英文标题】:Disallowing same input in C++ [closed] 【发布时间】:2018-11-13 00:09:30 【问题描述】:

我试图弄清楚如何阻止用户两次或多次输入相同的输入。例如,程序要求用户输入 3 个输入,而不是相同的输入。但是现在我的程序仍然继续选择相同的输入。如果用户输入B2 3 次,则选择它 3 次。输出将是You have chosen these lots: B2 B2 B2,这应该是不可能的。

我的输入是数组顺便说一句。 code[3].

我希望它能够读取之前相同的输入并说它已经被选中,选择另一个作为输入。

我更喜欢使用strcmp

#include <iostream>
#include <iomanip>
#include <string.h>
#include <fstream>
#include <conio.h>

char code[3][10];

for(int a=0; a<3; a++)

    do
    
        cout << "Please enter the lot you are interested in (A1-A7 / B1-B7): ";
        cin >> ws;
        cin.getline(code[a], 10);

        if((strcmp(code[a], "A4") == 0) || (strcmp(code[a], "A6") == 0) || (strcmp(code[a], "B1") == 0)))
        
            cout << "ERROR: Sorry! The house you chose has already been booked! \n\n"; // this are for booked lots already from the system
        
        else if((strcmp(code[a], "A1") == 0) || (strcmp(code[a], "A2") == 0) || (strcmp(code[a], "A3") == 0) ....
        
            cout << "SUCCESS: You have chosen the LOT " << code[a] << endl << endl;
        
        else
        
            cout << "ERROR: Sorry! The lot you entered is unavailable!" << endl << endl;
            // i added strcpy(code[a], "A4"); to trick the system, and it works out. 
        


    while((strcmp(code[a], "A4") == 0) || (strcmp(code[a], "A6") == 0) || (strcmp(code[a], "B1") == 0));

【问题讨论】:

请edit您的问题并附上您的代码。 好吧编辑了,@anatolyg 将字符串放入std::set&lt;std::string&gt;。虽然集合的大小小于n,但请阅读另一个答案。当集合包含一个答案时,不要接受它。 请添加您对code 的定义/声明。您在文本中添加了code[3],但将其放入代码中会更清楚。是string code[3]吗?我试图猜测;更好地防止人们猜测,并发布您的完整代码。包括和#include &lt;whatever&gt;,等等。见minimal reproducible example。 使用std::string 比使用字符数组更容易。例如,您可以使用operator==std::string 进行比较。 【参考方案1】:

试试这个:

int numValid = 0;
string in1, in2, in3;
while(numValid < 3)
    if(numValid == 0)
        cin >> in1;
        numValid++;
    
    else if(numValid == 1)
        cin >> in2;
        if(in1.compare(in2) == 0)
            cout << "The first and second entries match. Please try again" << endl;
        
        else
            numValid++;
    
    else
        if(in1.compare(in3)) == 0 || in2.compare(in3) == 0)
            cout << "Your third entry matches a prior entry. Please try again" << endl;
        
        else
            numValid++;
    


cout << "You have chosen these lots: " << in1 << " " << in2 << " " << in3 << endl;

【讨论】:

这里有几个问题,例如:(1)operator&lt;&lt;不适用于cin(2)strcmp参数是const char*不是std::string 值得一提的是,我使用数组作为输入code[a]。那我可以在那里做什么?我不熟悉你的方法。非常新手 谢谢@BenVoigt,IDE 自动更正使我变得柔软,并修正了我的错误。【参考方案2】:

如果您必须以不同的方式看待问题,您会发现根本不需要字符串或更高级别的数据结构。

输入都是一个字符和一个数字。如果你把它读成一个字符和一个数字,你可以使用一个二维数组,

bool inuse[2][7] = ;

存储任何批次的状态。 inuse[character][digit-1] 告诉您该特定字符和数字组合是否曾被看到和设置过。

围绕它的是通常的输入验证,以确保用户输入了可用的内容。

char group;
unsigned int index;

cin >> group >> index; // get one character and one number
if (cin) // Above reads succeed and data is good.

    if ((group == 'A' or group == 'B') and (index > 0 and index <= 7))
     // input ranges are valid
        int groupnum = group -'A'; // for any sane character encoding 
                                   // 'A' = 0, 'B' = 1, 'C' = 2 ...
        unsigned int number = index - 1; // arrays are origin 0
        if (not inuse[groupnum][number])
        
            cout << "Lot " << group << index << "selected\n";
            inuse[groupnum][number] = true; // mark as selected
        
        else
        
            cout << "Lot " << group << index << "already selected.\n";
        
    
    else
    
        cout << "Invalid input.\n";
    

else
 
    cout << "Invalid input.\n";
    cin.clear();
    // bit of a blind spot here if some fool closes the console. Check for eof
    // and exit the program if this is a concern.

cin.ignore(numeric_limits<streamsize>::max(), '\n'); // discard remainder of line

【讨论】:

【参考方案3】:

检查第二个输入是否等于第一个输入:

if (strcmp(code[1], code[0]) == 0)

    cout << "This input appeared earlier. Please enter another input\n";

检查第三个输入是否等于第一个或第二个输入,从字面上看:

if (strcmp(code[2], code[0]) == 0 || strcmp(code[2], code[1]) == 0)

    cout << "This input appeared earlier. Please enter another input\n";

但是,如果您想将其扩展到 3 个以上的输入,您应该保存所有早期输入的列表(如 Biffen 建议的那样):

std::set<std::string> earlierInputs;
...
cin.getline(code[a], 10);
auto result = earlierInputs.insert(code[a]);

if (!result.second)

    cout << "This input appeared earlier. Please enter another input\n";

此代码(需要使用 C++ 标准库)将新输入插入到所有早期输入的 set 中。 result 是一个数据结构,其second 元素告诉insert 操作是否成功(即新输入是否尚未出现在set 中)。

这个略显晦涩的代码最终是为了获得最佳性能;还有其他一些方法可以实现这一点 - 请参阅 this related answered question。

【讨论】:

是的,我更喜欢第一种方法,事实上我之前也尝试过,但令我惊讶的是,它只是给了我一个无限循环。甚至我输入的第一个输入也只是读取与之前输入的相同输入,这是没有的。需要更多类似于第一种方法的帮助,因为我还不熟悉或教过后一种方法

以上是关于在 C++ 中不允许相同的输入 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

当问题在C++中以相反的顺序要求输入时如何显示用户输入字符串[关闭]

成员声明中不允许使用 C++ 限定名称

Laravel 中不允许使用奇怪的 405 方法

bitmapStrokeString 在 C++ 中不起作用 [关闭]

如何在 C++ 视觉中创建 UI [关闭]

BootstrapVue - 数字表单输入在 Firefox 中不起作用