Использование strcmp () для сравнения двух массивов C-строк

Мой проект состоит в том, чтобы создать программу банковского счета, в которой пользователь вводит номер счета и пароль, чтобы делать что-либо в программе. Используемые номера учетных записей и пароли должны храниться в виде строк C (файл заголовка строки не допускается). Я считаю, что проблема, с которой я столкнулся, связана с функцией strcmp. Вот моя функция, в которой возникает проблема.

void get_password(int num_accounts, char **acc_num, char **password)
{
    char account[ACCOUNT_NUMBER];
    char user_password[PASS_LENGTH];

    std::cout << "\nEnter the account number: ";
//  std::cin.getline(account, ACCOUNT_NUMBER);
    std::cin >> account;

    int i = 0;

    do
    {
        if (strcmp(account, *(acc_num + i)) != 0)
        {
            i++;
        }
        else
            break;
    } while (i <= num_accounts);

    if (i == num_accounts)
    {
        std::cout << "\nCould not find the account number you entered...\nExiting the program";
        exit(1);// account number not found
    }

    std::cout << "\nEnter the password: ";
//  std::cin.getline(user_password, PASS_LENGTH);
    std::cin >> user_password;

    if (strcmp(user_password, *(password + i)) != 0)
    {
        std::cout << "\nInvalid password...\nExiting the program";
        exit(1);// incorrect password
    }
    else
    {
        std::cout << "\nAccount number: " << account
        << "\nPassword: " << user_password << "\n";
        return;
    }
}

acc_num и пароль представляют собой массивы C-строк. Когда я запускаю / отлаживаю программу, она вылетает при первом операторе if. Думаю, мой вопрос в том, правильно ли я использую функцию strcmp или есть проблема с указателями, которые я использую.


person BlackRockCitizen    schedule 07.02.2016    source источник
comment
Если строковый заголовочный файл не разрешен, конечно, вы тоже не можете использовать strcmp()?   -  person user207421    schedule 07.02.2016
comment
если вы не можете #include <string> вы #include <cstring> или #include <string.h>?   -  person SegFault    schedule 07.02.2016
comment
@EJP Он, вероятно, имел в виду <string>, а не <cstring>.   -  person Anmol Singh Jaggi    schedule 07.02.2016
comment
Вам нужно показать, как эта функция вызывается с определением и инициализацией каждого параметра.   -  person pcarter    schedule 07.02.2016
comment
я бы всегда говорил acc_num[i], а не *(acc_num + i). Означает то же самое, но более читабельно и идиоматично.   -  person pm100    schedule 07.02.2016
comment
@Jongware Это был пограничный вандализм. Это вопрос о языке C ++, и, удалив тег C ++, вы полностью изменили значение фразы заголовок строки в вопросе. (Я восстановил правильные теги, c ++ и c-строки.)   -  person David Schwartz    schedule 07.02.2016
comment
@Jongware Речь идет о строках в стиле C, отсюда и тег c-strings. Речь идет совсем не о языке C, поэтому тега c быть не должно. Это явно вопрос языка C ++.   -  person David Schwartz    schedule 07.02.2016
comment
Прошу прощения за недоразумение, я включил заголовочный файл <cstring>, а заголовок <string> не разрешен. Мой вопрос касается строк C, а не строк C ++.   -  person BlackRockCitizen    schedule 07.02.2016
comment
Как насчет того, чтобы спросить OP, какой строковый заголовок он / она не может использовать. В C ++ есть три разных заголовка, на которые можно ссылаться. <string>, который определяет std::string (среди прочего), <string.h>, который является заголовком C, который объявляет такие функции, как strcmp(), и <cstring>, который является заголовком C ++, который (в общих чертах) предоставляет те же функции, что и <string.h>, но в пространстве имен std.   -  person Peter    schedule 07.02.2016
comment
@BlackRockCitizen Чтобы избежать такой путаницы в будущем, не используйте тег c, если ваш вопрос касается кода, написанного на C ++ (и который должен быть скомпилирован с помощью компилятора C ++), даже если этот же код также будет разрешен для C.   -  person David Schwartz    schedule 07.02.2016


Ответы (2)


Ваш цикл будет выполняться, даже если num_accounts равно 0. Кроме того, вы выполняете доступ к массиву за пределами диапазона, записывая while (i <= num_accounts); вместо while (i < num_accounts);.

Лучше было бы написать так:

while (i < num_accounts)
{
    if (strcmp(account, *(acc_num + i)) == 0)
    {
        // match found!
        break;
    }
    i++;
}
person Anmol Singh Jaggi    schedule 07.02.2016
comment
Что означает «когда-нибудь после того, как будет 0 учетных записей»? И это не «вероятно», но наверняка, что он слишком часто зацикливается. - person user207421; 07.02.2016
comment
Я имел в виду, что цикл будет выполняться, даже если num_accounts равен 0 (что, я думаю, нежелательно). - person Anmol Singh Jaggi; 07.02.2016
comment
Так что исправь свой пост, чтобы так сказать. В настоящее время это бессмысленно. - person user207421; 07.02.2016

Вы предполагаете, что существует хотя бы одна учетная запись, и вы слишком часто зацикливаетесь. Более безопасный способ написать это будет следующим образом:

for (int i = 0; i < num_accounts && !strcmp(account, accnum[i]); i++)
    ;

или соответствующий while цикл. do/while здесь не подходит.

person user207421    schedule 07.02.2016