使用scanf创建新的struct对象

时间:2018-04-08 01:31:46

标签: c struct scanf

您好我正在创建一个包含用户列表的简单程序(基于下面的结构),我正在尝试根据用户输入创建新用户,我要求每个属性单独使用{ {1}}。但是我遇到了结构限制的问题,例如id应该最多10个字符,而nome最多可以有25个字符。这是我的更多上下文的代码:

scanf

使用上面给出的代码,如果我为第一个输入键入10个以上的字符,则忽略接下来的2个字符。我的第3个scanf总是被忽略,一个用于组。这里的任何人都可以帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:3)

scanf的问题在于它停止转换字符时有问题 更多在输入缓冲区中(因为用户输入的内容超过了您的预期),然后scanf会将这些字符留在那里。 特别是换行符(当用户按 ENTER 时输入) 保留在输入缓冲区中,这会导致后续调用的问题 scanf读取字符或字符串。所以在这种情况下你必须"清洁"输入缓冲区, 这样下一个scanf就不会消耗之前scanf次呼叫的剩余部分。

您可以在每scanf

之后使用此功能
void clean_stdin(void)
{
    int c;
    while((c = getchar()) != '\n' && c != EOF);
}

然后你可以这样做:

printf("\nId: ");
scanf("%10s", (*userPtr).id); // no need for &, id is char[]
clean_stdin();

printf("\nName: ");
scanf("%25s", (*userPtr).name); // same here
clean_stdin();

printf("\nGroup: ");
scanf("%c", &(*userPtr).group);
clean_stdin();

printf("\nScore: ");
scanf("%f", &(*userPtr).score);

另请注意,如果ID的最大长度为10,那么你的方式就是 buffer必须长度为11,因为在C中你需要终止字符串 '\0' - 终止字节。所以改变你的结构:

struct user {
  char id[11];
  char name[26];
  char group;
  float score;
};

还要记住,使用像这样的指针

struct user *userPtr, newUser;
  userPtr = &newUser;

  printf("\nId: ");
  scanf("%10s", (*userPtr).id);
  ...

没有必要,它实际上使代码更难阅读。你可以这样做:

void createNewUser() {
    struct user newUser;

    printf("\nId: ");
    scanf("%10s", newUser.id);
    clean_stdin();
    ...

    printf("\nScore: ");
    scanf("%f", &newUser.score);
    ...
}