c - fgets() 和 scanf() 的区别

标签 c user-input scanf fgets

这是我的代码。我不想使用 scanf() 来读取名字,我尝试使用 fgets() 但是在我输入名字和年龄之后,第二次和第三次我的程序运行不需要 age 的 for 循环。

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

struct student
{
    char name[15];
    int age;
};


int main()
{
    int i;
    struct student s[A];
    for (i = 0 ; i < A ; i++)
    {
        printf("enter the names and age\n");
        fgets(s[i].name, 10, stdin);
        scanf("%d", &s[i].age);
    }
    printf("\n\n");

    for (i = 0 ; i < A ; i++)
    {
        printf("%s\t%d\n", s[i].name, s[i].age);
    }
    return 0;
}

它不起作用,为什么?

但是当我将 fgets 替换为

scanf("%s%d",s[i].name,&s[i].age);

一切正常

最佳答案

The difference between fgets() and scanf()

fgets(...) 通常读取直到收到 '\n'

scanf("%d", ...) 通常:
1. 读取并丢弃前导空白。
2. 读取数字输入(符号、数字)直到扫描到非数字。
3. 非数字被放回stdin 用于下一个输入函数。


例子:

John回车
"John\n"fgets() 读入 s[0].name

21输入
21scanf("%d",...) 读入 s[0].age'\n' 放回stdin

"\n"fgets() 读入 s[1].name

M
"M"scanf("%d",...) 读取,s[1].age 中没有任何内容。 'M' 放回 stdin

ary输入
"Mary\n"fgets() 读入 s[2].name

19输入
19scanf("%d",...) 读入 s[2].age'\n' 放回stdin

"\n"fgets() 读入 s[3].name


备选方案:要读取 2 行,调用 fgets() 两次,然后解析:

int Scan_student(struct student *dest) {
  char buffer[2][80];
  dest->name[0] = '\0';
  dest->age[0] = -1;
  printf("enter the names and age\n");
  for (int i=0; i<2; i++) {
    if (fgets(buffer[i], sizeof buffer[i], stdin) == NULL) {
      return EOF; // stdin was closed, no more input (or input error)
    }
    buffer[i][strcspn(buffer[i], "\r\n")] = '\0'; // lop off potential trailing \n
  }
  // parse the 2 buffers: MANY options here - something simple for now.
  if (sscanf(buffer[0], " %14[-'A-Za-z ]", dest->name) != 1) {
    return 0;
  }
  if (sscanf(buffer[1], "%d", &dest->age) != 1) {
    return 0;
  }
  return 1;
}


int i;
struct student st[3];
for (i = 0 ; i < sizeof(st) / sizeof(st[0]) ; i++) {
  if (Scan_student(&st[i]) != 1) break;
}

关于c - fgets() 和 scanf() 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34371391/

相关文章:

C复数和printf

java - 修复我的循环并需要输入检查器、Java 方面的帮助

控制台应用程序的 C# 箭头键输入

java - 在正在运行的 GUI 环境中运行 Java 方法的最佳实践

c - 使用 float 作为正确类型的输入验证

c - scanf 导致段错误?

c - C 中的结构问题

c++ - 如何在 RAND 函数中获得更小的比例

c - 如何加入/分离/清理每个函数调用创建的动态 malloc 线程?

c - 在以相同模式结尾的文件中搜索整数 block