c - 使用 scanf 创建新的结构对象

标签 c struct scanf

你好我正在创建一个包含用户列表的简单程序(基于下面的结构),我正在尝试根据用户输入创建新用户,我在其中分别使用 scanf 请求每个属性.但是我在结构限制方面遇到了麻烦,例如 id 最多应该有 10 个字符,nome 最多可以有 25 个字符。这是我的代码以获得更多上下文:

struct user {
  char id[10];
  char name[25];
  char group;
  float score;
};

struct user list[25];
int registered = 0;

void createNewUser() {
  struct user *userPtr, newUser;
  userPtr = &newUser;

  printf("\nId: ");
  scanf("%10s", &(*userPtr).id);
  printf("\nName: ");
  scanf("%25s", &(*userPtr.name);
  printf("\nGroup: ");
  scanf("%c", &(*userPtr).group);
  printf("\nScore: ");
  scanf("%f", &(*userPtr).score);

  insert(newUser);

  printf("%10s\n", list[0].id);
  printf("%25s\n", list[0].name);
  printf("%c\n", list[0].group);
  printf("%.1f\n", list[0].score);
}

void insert(struct user newUser) {
  if (registered < 25){
    list[registered] = newUser;
    registered += 1;
  }
}

使用我上面提供的代码,如果我在第一个输入中键入超过 10 个字符,则接下来的 2 个将被忽略。而我的第 3 个 scanf 总是被忽略,那个是针对组的。这里有人可以帮我解决这个问题吗?

最佳答案

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,则您的方式 缓冲区的长度必须为 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);
    ...
}

关于c - 使用 scanf 创建新的结构对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49713566/

相关文章:

c - Scanf 程序访问被拒绝

C++ Tweetnacl 散列文件而不将整个文件读入内存

c - 读写互斥

c - 在c中实现ls命令

c++ - LLVM 的位码对函数参数的错误检测

c++ - 如何让 operator++ 继续到链表中的下一个节点指针?

c - 从文件 txt 中分割字符串

c++ - 如何读取二进制文件来计算哈夫曼树的频率?

c - 看似不可能输出链表

C getchar 与 scanf