Есть ли способ зациклить функцию strcmp на языке c?

Я новичок в университете и в настоящее время изучаю язык C. Вчера вечером я обнаружил действительно большую проблему с моим кодом, но я ничего не могу исправить своими ужасными навыками ... Вы можете помочь мне решить эту проблему?

(состояние)

  • вы пытаетесь войти с помощью id / pw и имеете только 3 шанса.
  • на каждом по 5 id и pw.
  • если id не существует, распечатайтеid does not exist .
  • если идентификатор существует, но pw не совпадает, выведитеpw does not match .
  • если id и pw совпадают, выведитеlogin successful и выйти из программы.

есть ли способ зациклитьstrcmp какие функции отмечены?

Вот код ниже.

#include <stdio.h>
#include <string.h>

int main(void) {
    char id0[] = "user1";
    char id1[] = "user2";
    char id2[] = "user3";
    char id3[] = "user4";
    char id4[] = "user5";

    char pw0[] = "pass1";
    char pw1[] = "pass2";
    char pw2[] = "pass3";
    char pw3[] = "pass4";
    char pw4[] = "pass5";

    char idsol[100] = { 0 };
    char pwsol[100] = { 0 };

    int idmat = 1;
    int pwmat = 1;
    int logstack = 0;
    for (int i = 0; i <= 2;) {
        logstack = i;
        rewind(stdin);
        printf("ID: ");
        scanf_s("%s", idsol, sizeof(idsol));
        printf("PW: ");
        scanf_s("%s", pwsol, sizeof(pwsol));

        if (strcmp(idsol, id0) == 0) { //i want to make these 5 blocks in one command.
            idmat = 0;
            if (strcmp(pwsol, pw0) == 0) {
                pwmat = 0;
            }
        }
        if (strcmp(idsol, id1) == 0) {
            idmat = 0;
            if (strcmp(pwsol, pw1) == 0) {
                pwmat = 0;
            }
        }
        if (strcmp(idsol, id2) == 0) {
            idmat = 0;
            if (strcmp(pwsol, pw2) == 0) {
                pwmat = 0;
            }
        }
        if (strcmp(idsol, id3) == 0) {
            idmat = 0;
            if (strcmp(pwsol, pw3) == 0) {
                pwmat = 0;
            }
        }
        if (strcmp(idsol, id4) == 0) { //these 5 blocks!!!
            idmat = 0;
            if (strcmp(pwsol, pw4) == 0) {
                pwmat = 0;
            }
        }
        if (idmat != 0) {
            printf("ID does not exist.\n");
            i++;
            idmat = 1;
        }
        else if (idmat == 0 && pwmat != 0) {
            printf("PW does not match.\n");
            i++;
            idmat = 1;
        } else {
            logstack = 0;
            break;
        }
    }
    if (logstack >= 2) {
        printf("login failed.\n");
    } else {
        printf("login successful!\n");
    }
    return 0;
}

Спасибо за любой комментарий! хорошего дня

#
Источник
  • 2
    Прочтите о массивах и структурах.
Codelisting
за 4 против
Лучший ответ

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

#include <stdio.h>
#include <string.h>
int main(void) {
    char id0[] = "user1";
    char id1[] = "user2";
    char id2[] = "user3";
    char id3[] = "user4";
    char id4[] = "user5";

    char pw0[] = "pass1";
    char pw1[] = "pass2";
    char pw2[] = "pass3";
    char pw3[] = "pass4";
    char pw4[] = "pass5";

    /* gather strings in arrays */
    char* ids[] = { id0, id1, id2, id3, id4 };
    char* pws[] = { pw0, pw1, pw2, pw3, pw4 };

    char idsol[100] = { 0 };
    char pwsol[100] = { 0 };

    int idmat = 1;
    int pwmat = 1;
    int logstack = 0;
    for (int i = 0; i <= 2;) {
        logstack = i;
        rewind(stdin);
        printf("ID: ");
        scanf_s("%s", idsol, sizeof(idsol));
        printf("PW: ");
        scanf_s("%s", pwsol, sizeof(pwsol));

        /* use the arrays for looping */
        for (int j = 0; j < 5; j++) {
            if (strcmp(idsol, ids[j]) == 0) {
                idmat = 0;
                if (strcmp(pwsol, pws[j]) == 0) {
                    pwmat = 0;
                }
            }
        }
        if (idmat != 0) {
            printf("ID does not exist.\n");
            i++;
            idmat = 1;
        }
        else if (idmat == 0 && pwmat != 0) {
            printf("PW does not match.\n");
            i++;
            idmat = 1;
        }
        else { logstack = 0; break; }
    }
    if (logstack >= 2) {
        printf("login failed.\n");
    }
    else { printf("login successful!\n"); }

    return 0;
}

Другой способ - поместить строку прямо в массивы:

#include <stdio.h>
#include <string.h>
int main(void) {
    char ids[][6] = {
        "user1",
        "user2",
        "user3",
        "user4",
        "user5"
    };

    char pws[][6] = {
        "pass1",
        "pass2",
        "pass3",
        "pass4",
        "pass5"
    };

    char idsol[100] = { 0 };
    char pwsol[100] = { 0 };

    /* omit: same as the first code */
}
  • 2
    rewind(stdin); кажется некорректным и может вызвать сбои в автоматических тестах :)
  • 0
    MikeCAT / Спасибо !!! Я сделал 2d-массив, и ваше решение сработало!
за 1 против

Я только что определил функцию для выполнения цикла и изменил определения вашего массива на список строк. Код ниже (следуйте пояснениям в коде):

#include <stdio.h>
#include <string.h>

#define NTIMES 3  /* ask three times for a password */

/* this table organization allows you to iterate for each pair of ids[i]
 * and pws[i]. */
char *ids[] = {
        "user1",
        "user2",
        "user3",
        "user4",
        "user5",
        NULL, /* to indicate we are finished this controls how the end of
               * the list is reached below */
};
char *pws[] = {
        "pass1",
        "pass2",
        "pass3",
        "pass4",
        "pass5", /* don't need to add a NULL here, but there
                  * must be as many entries as for used ids */
};

/* this function searches the two tables above for a valid user/pass match */
int check_user(char *user, char *pass)
{
    int id;
    for (id = 0; ids[id] != NULL; id++) { /* iterate the list */
        if (0 == strcmp(ids[id], user)) { /* if user found */
            if (0 == strcmp(pws[id], pass)) { /* if pass matches */
                printf("Found user %d, id=%s\n", id, ids[id]);
                return id; /* found user, return value of id to know
                            * outside which user was selected. */
            } else {
                printf("PW does not match\n");
                /* we continue for the next pair in the loop */
            }
        }
    }
    /* we ended the loop without a valid user/pass match */
    printf("ID %s does not exist, or password incorrect\n", user);
    return -1; /* not found, we return a number out of the valid range */
}

int main(void) {

    /* initializing these variables is not neccessary as you assign them
     * (by reading into them from stdin) before using.  But it is a good
     * practice, so it is more difficult that you forget initializing
     * variables that should have a default value. */
    char idsol[100] = { 0 };
    char pwsol[100] = { 0 };

    // int idmat = 1; // unnecessary
    // int pwmat = 1; // unnecessary
    // int logstack = 0; // unnecessary
    /* we need to declare times outside the for loop, because we are using
     * the last value assigned to it in the loop, so in case we get out of
     * the loop prematurely, we know we got a valid user. */
    int times = -1; /* we initialize, for the same reason explained above */
    for (times = 0; times < NTIMES; times++) {
        // logstack = i;  // unnecessary
        // rewind(stdin); // unnecessary
        printf("ID: ");
        if (!fgets(idsol, sizeof idsol, stdin)) {
            break;  /* EOF on input, get out of the loop */
        }

        char *id_pointer = strtok(idsol, "\n"); /* take off the last
                                                 * newline */
        // scanf_s("%s", idsol, sizeof(idsol)); // scanf_s is not standard
        printf("PW: ");
        if (!fgets(pwsol, sizeof pwsol, stdin)) {
            break; /* EOF while reading input, get out of the loop */
        }

        char *pass_pointer = strtok(pwsol, "\n"); /* take off the newline */
        // scanf_s("%s", pwsol, sizeof(pwsol)); // scanf_s is not standard

        /* this calls the function above that tests a username/password
         * and prints the messages in the block below */
        if (check_user(id_pointer, pass_pointer) >= 0)
            break; /* get out of the loop */

/* this was the code you wanted to eliminate, so here it is, commented */
//      if (strcmp(idsol, id0) == 0) { //i want to make these 5 blocks in
// one command.
//          idmat = 0;
//          if (strcmp(pwsol, pw0) == 0) {
//              pwmat = 0;
//          }
//      }
//      if (strcmp(idsol, id1) == 0) {
//          idmat = 0;
//          if (strcmp(pwsol, pw1) == 0) {
//              pwmat = 0;
//          }
//      }
//      if (strcmp(idsol, id2) == 0) {
//          idmat = 0;
//          if (strcmp(pwsol, pw2) == 0) {
//              pwmat = 0;
//          }
//      }
//      if (strcmp(idsol, id3) == 0) {
//          idmat = 0;
//          if (strcmp(pwsol, pw3) == 0) {
//              pwmat = 0;
//          }
//      }
//      if (strcmp(idsol, id4) == 0) { //these 5 blocks!!!
//          idmat = 0;
//          if (strcmp(pwsol, pw4) == 0) {
//              pwmat = 0;
//          }
//      }
//      if (idmat != 0) {
//          printf("ID does not exist.\n");
//          i++;
//          idmat = 1;
//      }
//      else if (idmat == 0 && pwmat != 0) {
//          printf("PW does not match.\n");
//          i++;
//          idmat = 1;
//      } else {
//          logstack = 0;
//          break;
//      }
    }
    /* i have changed slightly this code also to use a single constant
     * (by using its name, so i can modify the number of times to ask for
     * a password, by editing only in one place (at the top). */
    if (times < NTIMES) {
        printf("login successful!\n");
        return 0;  /* successful exit code, see exit(3) for details */
    } else {
        printf("login failed.\n");
        return 1;  /* some error happened */
    }
}
Codelisting
Популярные категории
На заметку программисту