【问题标题】:C double printf() when a space is put in my scanf()C double printf() 当我的 scanf() 中有空格时
【发布时间】:2021-06-05 16:00:55
【问题描述】:

我一直在努力让这段代码正常工作:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char const **argv) {
    char buf[100];
    int var = 0;
    do {
        printf("Write a number :\n");
        scanf("%s", buf);
    } while ((int)strtol(buf, NULL, 10) == 0);

    return 0;
}

在控制台中是这样的:

chaouchi@chaouchi:~/workspace/Demineur$ ./a.out
Write a number :
f 10
Write a number :
chaouchi@chaouchi:~/workspace/Demineur$

我不明白为什么程序在while 循环的第二次迭代中停止并忽略了我的scanf()

【问题讨论】:

  • 不相关,但为了避免从一开始就养成一个坏习惯:始终限制从外部源读取的数据长度为缓冲区长度。在这里,使用scanf 读取buf 的输入很容易出现缓冲区溢出,这是最常见的安全漏洞之一。请参阅手册页,了解如何正确限制字符数。
  • 你检查scanferrno的返回值了吗?
  • 你为什么要使用strtol?如果您要使用 scanf,只需使用%ld 转换说明符。您必须检查 scanf 返回的值。

标签: c while-loop scanf strtol


【解决方案1】:

步骤如下:

  • 第一次迭代打印 Write a number : 和换行符,
  • scanf("%s", buf) 没有从标准输入读取,所以需要输入,
    • 您输入f 10 和回车键
    • scanf("%s", buf) 读取 f 并停在空间,
  • strtol(buf, NULL, 10) 返回0,所以循环继续
  • 第二次迭代打印 Write a number : 和换行符,
  • scanf("%s", buf) 读取 10 并停在换行符处,
  • strtol(buf, NULL, 10) 返回10,所以循环退出
  • 程序以0 状态结束(成功)。

这是您观察到的:如果您提供多个单词,多个scanf() 调用会在终端请求更多输入之前读取它们。

【讨论】:

  • 谢谢,我明白了。我的问题是我不知道 scanf() 在 stdin 中没有要读取的内容时请求输入。编辑:不能投票给我声望点少于 15。
  • 我只有 1 个问题,scanf 是否会在上一个循环中他在 stdin 中的每个循环中保存一个指向 remeber 的指针?
  • @MeryVorente: scanf() 不这样做,它是流结构。 FILE 对象是一个结构,它保存有关流的信息,例如当前位置,一个缓冲区,其中包含从设备或文件中读取但尚未被 getc()fgets()、@987654339 读取的字符@ 或 fread()。同样,缓冲区保存putc()fputsfprintffwrite 写入的字节,直到需要将其刷新到终端或文件系统。通常,当从连接到终端的stdin 读取输入时,会从用户读取整行输入...
  • ... 到流缓冲区中,getc() 从中读取单个字节,scanf() 读取足够的字节来执行格式字符串中指定的转换,即:直到读取到没有的字节更长的匹配预期的语法。这个字节被推回流中,就像被ungetc() 一样,将被下一个读取函数读取。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-07
  • 1970-01-01
  • 2019-10-25
  • 1970-01-01
  • 1970-01-01
  • 2019-02-13
相关资源
最近更新 更多