c - 我是否错误地使用了 scanf?

标签 c

每行输入都是一行命令后跟数字(退出情况除外)。

我不知道我做错了什么。该段正在寻找存储命令,然后执行存储操作:

    char command[20];
    while(strcmp(command, "exit") != 0)
    {
        /*scans for command strings inputted*/
        scanf(" %s", command);
        /* handles store command*/
        if(strcmp(command, "store") == 0)
        {   
            memory[0] = 1;
            scanf("%d %d %d %d %d", &startx, &starty, &finishx, &finishy, &number);
            for( i = startx; i < finishx; i++)
            {
                for(j = starty; j < finishy; j++)
                {
                square[i][j] = number;
                }
            }
        }
     }

最佳答案

是的,你用错了(a)。线路:

scanf(" %s", command);

没有对输入进行边界检查。如果有人在您的程序中输入超过 19 个字符,它将溢出 char command[20] 并导致未定义的行为。

scanf 的两个主要问题是:

  • 将它与无限制的 %s 一起使用,因为无法控制输入的数据量。我最喜欢的说法是,scanf 是扫描格式化信息,没有多少less用户输入的格式化信息。
  • 不检查扫描了多少项目 - 扫描的项目可能少于您的预期。

如果您想正确执行此操作,请参阅 here .它使用 fgets 获取一行,防止缓冲区溢出并检测问题。

一旦你有了字符串形式的行,你就可以安全地 sscanf 它到你心中的内容,因为你知道长度的上限并且你总是可以返回到要重新扫描的字符串的开头(对于输入流来说不是一件容易的事)。


您的代码的其他问题包括:

  • 未初始化缓冲区上的初始 strcmp。它可能实际上(任意)设置为exit,这会导致您的循环不能太开始。 更多 可能是它根本不是有效的 C 字符串,这意味着 strcmp 将从缓冲区的末尾运行。这不一定会有好结果。
  • 不检查您输入的所有数字项目是否正确。您可以通过检查 scanf 的返回值(或者 sscanf 如果您按照我的建议使用链接到此处的坚如磐石的输入函数)来做到这一点 - 它应该是五个但是输入 1 hello 2 3 4 将导致返回代码为 1(并且除了 startx 之外的所有代码都保持不变)。
  • 没有输入范围检查。由于 square 的维度有限,您应该检查输入以确保您不会写在数组之外。这两个数字都太大了负数。

(a) 语法上您所拥有的是正确的。但是,从实际语义的角度来看(即,您打算发生什么与可能发生什么),您的代码中存在一个大到足以让空中客车 A380 飞过的漏洞:-)

关于c - 我是否错误地使用了 scanf?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9459560/

相关文章:

C素数分解(循环失败?)

c - Linux/include 目录枚举

c - A[i]+=A[i+1] 是一种循环中的数据依赖吗?可以向量化吗?

c - C 代码从 CentOS 迁移到 Windows ^

c - Sublime 文本识别扩展多行的功能

c - Powerpc arch 上的 gcc 内联汇编程序隐式函数声明

c++ - free():下一个大小无效(正常)&munmap_chunk():C中的无效指针

c - 在 C 中模拟可附加数组...有点

objective-c - 如何使用 Objective-C 测试数字是否在范围内?

c - 从文件中动态读取结构时 fread 不工作