【问题标题】:Why am I getting same results (as the first) in the C code?为什么我在 C 代码中得到相同的结果(与第一个结果相同)?
【发布时间】:2018-07-07 16:33:02
【问题描述】:

我用 C 语言编写了这段代码来创建多个用户,并使用在该程序中用户注册时提供的用户名和密码登录。但我得到的结果与我的第一个操作相同。

例如,我使用 uname 注册为 test1 并以 test123 身份通过,如果我在登录部分输入此信息,我将收到“登录成功”消息但是当我尝试输入任何随机名称并传入登录部分后,它只会显示“登录成功”消息。当我退出并重新运行程序时,如果我在登录时输入了错误的凭据,那么我将收到“无效的详细信息”消息,但之后如果我尝试使用正确的凭据登录,那么我也会收到“无效的详细信息”味精。知道代码有什么问题吗?

案例 1:使用正确的凭据。

输入 1

用户名 = test1

密码 = test123

输出 = 登录成功

输入 2

用户名 = 错误的用户名

密码=错误密码

预期输出 = 无效详情

但我得到的输出 = 登录成功

案例 2:首先使用错误的凭据

输入 1

用户名 = 错误的用户名

密码=错误密码

输出 = 无效的详细信息

输入 2

用户名 = test1

密码 = test123

预期输出 = 登录成功

但我得到的输出 = 无效的详细信息

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

struct database
{
  char user[20];
  char pass[20];
  char email[40];
}record;

int main()
{
    int count, choice, entries, i, j, ls, check=0;
    char mask;
    char fileDump[10000][50];
    char username[20];
    char password[20];
    FILE *fptr = fopen("E:\\login_practice.bin","ab+");
    char dump[256];
    Again:
    printf("Welcome to user authentication program v1.2\n");
    printf("\n1. Register\n");
    printf("\n2. Login\n");
    printf("\n3. Exit\n");
    printf("\nEnter your choice: ");
    scanf("%d", &choice);
    switch(choice)
    {
        case 1:
            printf("\nHow many user you want to register?\n");
            printf("\nUsers = ");
            scanf("%d", &entries);
            for(count=1; count<=entries; count++)
            {
                FILE *fp = fopen("E:\\email.bin", "ab+");
                printf("\nEnter your email: ");
                scanf("%s", &record.email);
                fprintf(fp, "%s\n", record.email);
                fclose(fp);

                printf("\nEnter a username: ");
                scanf("%s", &record.user);
                fprintf(fptr, "%s\n", record.user);

                printf("\nEnter a password: ");
                for(j=0; j<10; j++)
                {
                    mask = getch();
                    if(mask == 13)
                    {
                        break;
                    }
                    else
                    {
                        record.pass[j] = mask;
                        mask = '*';
                        printf("%c", mask);
                    }
                }
                fprintf(fptr, "%s\n", record.pass);
                printf("\nRegistration Successful.\n");
            }
            goto Again;
            break;

    case 2:
        i=0;
        while(fgets(dump, sizeof(dump),fptr))
        {
            strcpy(fileDump[i], dump);
            i++;
        }
        ls=i;
        printf("\nLines Scanned = %d\n", ls);
        printf("\nEnter your username: ");
        scanf("%s", &username);
        printf("\nEnter your password: ");
        for(j=0; j<10; j++)
        {
            mask = getch();
            if(mask == 13)
            {
                break;
            }
            else
            {
                password[j] = mask;
                mask = '*';
                printf("%c", mask);
            }
        }
        strcat(username, "\n");
        strcat(password, "\n");
        for(i=0; i<=ls; i+=2)
        {
            if(strcmp(fileDump[i], username)==0)
            {
                if(strcmp(fileDump[i+1], password)==0)
                {
                    check++;
                }
            }

        }
        if(check == 1)
        {
            printf("\nLogin Successful.\n");
        }
        else
        {
            printf("\nInvalid Details Entered!\n");
        }
        goto Again;
        break;

    case 3:
        exit(0);
        break;

    default:
        printf("\nBad Choice!\n");
        goto Again;
        break;
    }
fclose(fptr);
}

【问题讨论】:

  • 现在可能是learn how to debug your programs的好时机。
  • 请不要使用标签和goto 作为循环。几乎总是有更好的方法来处理它,即使在像你这样的情况下也是如此。
  • 强调这一点:Do not use goto. Ever.
  • check 变量仅在程序开始时设置为 0 一次。您要么不允许用户再次登录,要么将变量设置回 0。
  • 我认为为每个案例选项使用一个函数是个好主意

标签: c codeblocks


【解决方案1】:

始终了解您的数据。 scanf 不附加换行符。见this.

因此,当您执行strcat(username, "\n");strcat(password, "\n"); 时,实际上会将strcmp(fileDump[i], username)==0strcmp(fileDump[i+1], password)==0 的结果变为非零值。
check++; 行永远无法执行,因为它上面的比较测试被篡改为错误..

请务必阅读 cmets 中的建议;这一点很重要。 另请查看 strcmpstrcat 的文档。

【讨论】:

  • 感谢您的解决方案,但您能告诉我为什么文件中会打印 NULL 字符吗?
  • 编辑您的代码以反映 cmets 和此处建议的更改。然后我会尽力再看一遍。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-15
  • 2011-06-29
相关资源
最近更新 更多