【问题标题】:Structures repeating entered data in C在 C 中重复输入数据的结构
【发布时间】:2016-04-12 06:54:17
【问题描述】:

我正在开发一个“C”编程语言课程的项目。我有一个问题,我无法找到解决办法。问题在于我正在使用的结构。它需要我输入的任何数据并重复 6 次。我的代码是

对于结构:

    struct authstruct
    {
        char userName[MAXCHAR];
        char userPin[MAXCHAR];
    };

正在接收输入的行

    struct authstruct usr;
    printf("Please enter your username\n");
    scanf("%s",usr.userName);
    while (fscanf(fident, "%s%s", auth.userName, auth.userPin) != EOF)
    {
        printf("%s", usr.userName);
    };

请注意,我已将其设置为打印接收到的代码以用于测试目的。例如,如果您输入了

test

它会踢出去

testtesttesttesttesttest

整个代码(忽略不相关的功能,没有上面的编辑)是:

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

/* Defining of constants */
#define MAXCHAR 10
#define MAXATTEMPTS 3
#define SIZE 10

/* Prototypes */
int AuthFunc(void);

/* Prototype of structure for Authentication Function */
 struct authstruct
{    
    char userName[MAXCHAR];
    char userPin[MAXCHAR];
};

int main(VOID)
{
    int login;
    login = AuthFunc();
    if (login == -1)
    {
        printf("namepass.txt could not be found\nPlease check for file and try again\n");
    }
    else if (login == 1)
    {
        printf("You have tried too many times to login\nPlease restart and try again\n");
    }
    else if (login == 0)
    {
        printf("Success!");
    }
    return 0;
}

/* This function authenticates the user */
int AuthFunc(void)
{
    int i = 0;
    FILE *fident;
    fident=fopen("namepass.txt", "r");
    if (fident==NULL)
    {
        return -2;
    }

    printf("Hello! Please follow my instructions\n");
    struct  authstruct auth;
    for (i=0; i < MAXATTEMPTS; i++)
    {
        struct authstruct usr;
        printf("Please enter your username\n");
        scanf("%s",usr.userName);
        while (fscanf(fident, "%s%s", auth.userName, auth.userPin) != EOF)
        {
            if ((strcmp(usr.userName, auth.userPin)) == 0)
            {
                printf ("Please enter your password.\n");
                scanf ("%s",usr.userPin);
                if ((strcmp(usr.userPin, auth.userPin)) == 0)
                {
                    fclose(fident);
                    return 0;
                }
            }
        }
        printf("Incorrect username/password.\n");
    }    
    fclose(fident);
    return 1;
}

要运行它,您需要创建一个名为 namepass.txt 的新 .txt 文件,其中您选择的用户名/密码位于一行中,如下例所示

test    12345
test2    23456

我为这篇冗长的帖子道歉,我只是想尽可能地描述一下。这是在运行 OSX 10.11.4 的 Mac 上的 Xcode 7.3 中编译和运行的。如果您的机器上没有出现此问题,请告诉我,我将开始深入研究我的编译器设置。 谢谢你

【问题讨论】:

  • 至少您是在循环中第一次比较用户名和 pin...
  • ...而且您永远不会在两次尝试之间倒回文件。
  • if ((strcmp(usr.userName, auth.userPin)) == 0) --> if ((strcmp(usr.userName, auth.userName)) == 0)
  • 谢谢@SamiKuhmonen、BLUEPIXY 和 WhozCraig。当我做了你们都推荐的修复时,我能够修复这段代码。

标签: c xcode macos osx-elcapitan


【解决方案1】:

while (fscanf(fident, "%s%s", auth.userName, auth.userPin) != EOF) 看起来不对。 fscanf 返回 int,如果两个读数都通过,则为 2

修改为:

while (fscanf(fident, "%s%s", auth.userName, auth.userPin) == 2)

正如WhozCraigcomment 中提到的,您应该将文件倒回到开头或在for 循环中限制文件的打开和关闭AuthFunc

来自man fscanf

这些函数返回成功匹配和分配的输入项的数量,可以少于提供的,甚至 在早期匹配失败的情况下为零。

如果在第一次成功转换或发生匹配失败之前到达输入结尾,则返回值 EOF。 如果发生读取错误,也会返回 EOF,在这种情况下 设置了流的错误指示符(参见 ferror(3)),设置了 errno 来指示错误。

【讨论】:

  • 另外:1) fscanf() 应该如何知道一个字符串何时结束而另一个字符串何时开始? 2) findent 尚未初始化。
  • 1) != EOF 是为了那个我想 2) 我没有将 fident 的初始化添加到我一开始粘贴的短代码中,但是如果你仔细看大块的话在那里。
  • 非常感谢,这解决了我的问题,在 scanf("%s",usr.userName); 行之后添加行 rewind(fident); 添加所需的文件倒带,当与您和 @SamiKuhmonen 提供的修复配对时我允许这段代码完美运行。
猜你喜欢
  • 1970-01-01
  • 2016-03-24
  • 1970-01-01
  • 1970-01-01
  • 2012-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多