【问题标题】:Discarding extraneous characters in the stdin stream buffer丢弃标准输入流缓冲区中的无关字符
【发布时间】:2014-01-09 11:50:14
【问题描述】:

我想编写一个函数来从stdin 读取数据。该函数将被其他函数调用以提示用户输入数据。

void read_data(void) {
    // prompt the user by printing a message
    // printf("enter data:\n");

    int a;
    char name[40];
    scanf("%d", &a);

    // prompt for input again

    scanf("%39[^\n]", name);

    // do something with the data
}

为了使函数read_data 正常工作,stdin 流缓冲区中不应有任何无关字符,即它应该为空。该函数不知道在最后一次scanf 调用中输入了什么,并且输入缓冲区中可能存在整数和字符。

如何确保函数 read_data 正常工作?

【问题讨论】:

  • 只需使用fgets() 并逐行读取输入。比scanf() 好得多(包括安全性!)。
  • 后续对fgets() 的调用不会遇到同样的问题吗?如果输入字符串比我们传递给fgets 的缓冲区长怎么办?下一个fgets 调用将从stdin 缓冲区开始读取。
  • fgets() 吃掉所有尾随的换行符。如果你通过一个大小为LINE_MAX 的虫子,那么它保证能够保持任何线路。
  • 我希望你的意思是缓冲区 ;) 所以从stdin读取一行输入的万无一失的方法是char line[LINE_MAX]; fgets(line, LINE_MAX, stdin);?然后我可以安全地处理line 而不会弄乱stdin 缓冲区。
  • 缓冲区,当然 :) 是的,据我所知,LINE_MAX 是一个实现定义的宏,表示行数不应超过那么多字符。

标签: c scanf


【解决方案1】:
void read_data(void) {

 // prompt the user by printing a message
 // printf("enter data:\n");

 int a,c;
 char name[40];
 scanf("%d", &a);
 while((c=getchar()) != '\n');
 // prompt for input again

 scanf("%39[^\n]", name);
 while((c=getchar()) != '\n');
 // do something with the data
}

将第一个 scanf 用于

  while((c=getchar()) != ' ' && c != '\t' && c != '\n');

所以如果给定的字符是'\n',那么getchar函数获取字符并检查它是否是新行,如果它是新行,如果移动到更远的地方,它会到达换行符,所以stdin流缓冲区被清除。

【讨论】:

  • 如果有非空白字符,第一个scanf 调用将静默读取缓冲区,而不提示用户输入。
  • 如果输入缓冲区为空怎么办?然后你必须输入一个空格字符才能退出 while 循环。
  • 字符串的输入缓冲区为空或数字为空的情况
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-23
  • 1970-01-01
  • 2023-04-08
  • 1970-01-01
相关资源
最近更新 更多