Запрещение ввода одного и того же ввода в C ++

Я пытаюсь выяснить, как заблокировать один и тот же ввод дважды или более пользователем. Например, программа требует, чтобы пользователь ввел 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));
}

person iDamn    schedule 03.06.2018    source источник
comment
Пожалуйста, отредактируйте свой вопрос и укажите свой код.   -  person anatolyg    schedule 03.06.2018
comment
хорошо отредактировал, @anatolyg   -  person iDamn    schedule 03.06.2018
comment
Поместите строки в std::set<std::string>. Пока размер набора меньше n, прочтите другой ответ. Пока в наборе есть ответ, не принимайте его.   -  person Biffen    schedule 03.06.2018
comment
Пожалуйста, добавьте ваше определение / декларацию code. Вы добавили code[3] в текст, но его проще поместить в код. Это string code[3]? Я пытаюсь угадать; лучше не позволяйте людям угадывать и публикуйте свой полный код. В том числе и #include <whatever>, и все. См. минимальный воспроизводимый пример.   -  person anatolyg    schedule 03.06.2018
comment
извините за мое невежество @anatolyg, я снова отредактировал его с объявлением строки (char) и определениями. вот и все, что я думаю, относящееся к этой части программы. это также в функции, если это имеет значение, что не должно   -  person iDamn    schedule 03.06.2018
comment
Было бы проще использовать std::string, чем символьные массивы. Например, вы можете использовать operator== для сравнения с std::string.   -  person Thomas Matthews    schedule 03.06.2018


Ответы (3)


Если вам нужно взглянуть на проблему несколько иначе, вы увидите, что в строках или структурах данных более высокого уровня нет необходимости вообще.

Все входные данные состоят из одного символа и одной цифры. Если вы читаете это как один символ и одну цифру, вы можете использовать 2D-массив,

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
person user4581301    schedule 03.06.2018

Чтобы проверить, равен ли второй ввод первому:

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";
}

Однако, если вы хотите расширить его до более чем трех входов, вы должны держать список всех предыдущих входов (как предлагает Биффен):

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).

Этот слегка непонятный код в конечном итоге предназначен для обеспечения максимальной производительности; есть и другие способы реализовать это - см. этот связанный ответ на вопрос.

person anatolyg    schedule 03.06.2018
comment
да, я предпочитаю первый метод, и я действительно пробовал это раньше, но, к моему удивлению, он просто дал мне бесконечный цикл. даже ПЕРВЫЙ ввод, который я ввел, просто читается как тот же ввод, введенный ранее, а его нет. нужна дополнительная помощь, аналогичная первому методу, потому что я еще не ознакомлен и не обучен второму методу - person iDamn; 04.06.2018

Попробуй это:

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;
person Amanda    schedule 03.06.2018
comment
Здесь есть несколько проблем, например: (1) operator<< не работает с cin (2) strcmp аргументы const char* не std::string - person Ben Voigt; 03.06.2018
comment
Стоит отметить, что я использую массив для указанного ввода code[a]. так что я могу там делать? Я не знаком с вашим методом. очень новичок - person iDamn; 03.06.2018
comment
Спасибо @BenVoigt, я был смягчен функцией автозамены IDE, и я исправил свои ошибки. - person Amanda; 03.06.2018