【问题标题】:Return value of scanf()scanf() 的返回值
【发布时间】:2016-07-10 02:18:17
【问题描述】:

这是我的代码,用于重复从用户读取三个由空格分隔的变量。输入的格式应该是 'char int int'(例如 b 3 3 )。我使用 scanf 函数的返回值来确保输入正好是三个变量。

#include <stdio.h>

int main(void){
  int x, y, nargs;
  char command;

  while(1){
    nargs = scanf("%c %d %d", &command, &x, &y);
    printf("%d\n",nargs);

    if(nargs != 3){
      printf("error\n");
      break;
    }
  }
  return 0;
}

输入和输出:

g 4 4
3
b 3 3
1
error

第一行输入没问题。但是当我输入第二行时,它显示 scanf() 只从这一行读取一个变量。我的代码有什么问题?

【问题讨论】:

  • " %c%d%d" 是快速回答。使用fgets() 然后sscanf(buf, " %c%d%d",... 更好。 GTG

标签: c scanf


【解决方案1】:

问题是 \n 隐藏在您发送到标准输入的两个输入行之间的换行符。在第一个scanf 之后,您有一个'\n' 在输入流上挂起,然后您附加"b 3 3",因此整个缓冲区看起来像"\nb 3 3"

然后再次调用scanf 并且\n%c 匹配,在scanf 需要空格但缓冲区有'b' 因此将\n 分配给command 后它会失败。

你可以尝试匹配

nargs = scanf("%c %d %d ", &command, &x, &y);
                       ^

这样换行符就和之前的scanf一起吃掉了,来自cppreference

格式字符串中的任何单个空白字符都会消耗输入中所有可用的连续空白字符

【讨论】:

  • 知道了!但是有一个新问题,它无法读取我的第一行输入。我应该输入 g 4 4\n b 3 3\n 然后程序将 3 反馈给我。
  • 使用" %c%d%d" 而不是"%c %d %d " 开始时需要空间。最后有问题。
【解决方案2】:
nargs = scanf("%1s %d %d", &command, &x, &y);

问题在于一个字符的%c。如果您将其更改为%1s,您希望得到一个包含一个字符(相同)但没有问题的字符串。

使用%c 最好将结果发送到数组,并使用其索引访问内容。

【讨论】:

  • "%1s" 是个坏主意,char command; - 缓冲区溢出。
  • 为了扩展@chux 的注释,%1s 读入一个单字符字符串,它占用两个字节,一个用于数据,一个用于'\0' 终止符.
猜你喜欢
  • 1970-01-01
  • 2018-04-02
  • 1970-01-01
  • 2021-10-03
  • 1970-01-01
  • 2015-04-06
  • 1970-01-01
  • 1970-01-01
  • 2021-01-31
相关资源
最近更新 更多