【问题标题】:How to stop input overflowing via stdin如何通过标准输入停止输入溢出
【发布时间】:2020-08-23 11:47:26
【问题描述】:

我的程序应该通过标准输入接受输入并将字符串存储到大小为SIZE的数组中。

当我输入 7 个或更多值时出现问题;当程序在循环中运行时,仍然使用超出缓冲区大小的值,不断用 stdin 中剩余的内容填充buf(至少,我认为它是这样工作的)。

#define SIZE 8

char *readLine(char *buf, size_t size) {
    printf("$ ");
    fgets(buf, size, stdin);
    return buf;
}

int main() {
    char *buf = malloc(SIZE * sizeof(char));
    
    for (;;) {
        readLine(buf, SIZE);
        printf("> %s", buf);
    }   
}

我的输出,分别测试输入大小为 6、7 和 8:

$ abcdef
> abcdef
$ abcdefg
> abcdefg$ > 
$ abcdefgh
> abcdefg$ > h

我不明白的事情:

  • 为什么第 7 个值会让程序的输出看起来很奇怪?我认为第 7 个字符加上空字符可以正常工作?
  • 为什么buf 会填充超出SIZE 大小(在本例中为8)的值?

据此,我可以进行简单的更改/添加以实现我想要的吗?

【问题讨论】:

    标签: c memory-management malloc stdin fgets


    【解决方案1】:

    为什么第 7 个值会让程序的输出看起来很奇怪?我认为第 7 个字符加上空字符可以正常工作?

    fgets 不会读取过多的输入(超出您提供的缓冲区大小,不包括空字节的一个字节空间)。所以字符h 留在输入流中,然后被您下次调用fgets 消耗 - 读取h 和换行符\n。在读取换行符后,fgets 会终止读取进一步的输入。

    为什么 buf 会填充超过 SIZE 大小(本例中为 8)的值?

    它没有。如前所述,剩余的输入被读取,因此呈现出这样的外观。

    据此,我可以进行简单的更改/添加以实现我想要的吗?

    您可以检查fgets读取的缓冲区是否有换行符;如果不是,则读取并忽略输入流中的剩余字节。

    你可以这样做:

    void discard(const char *buf)
    {
        if(strchr(buf, '\n') == NULL) {
            /* No newline found, so read & discard everything.
            while(getchar() != '\n');
        }
    }
    
    char *readLine(char *buf, size_t size) {
        printf("$ ");
        if (fgets(buf, size, stdin) != NULL) {
            discard(buf);
        }
        return buf;
    }
    

    【讨论】:

    • 啊,感谢您澄清这一点。但是在你的最后一点上,假设没有换行符并且输入是 12 个字符长,我如何使它 ignore 文本的其余部分(超过第 7 个字符)?我是否计算出第 8 个索引并使其 = '/0'?这会忽略其余的吗?能够忽略size 之外的其他输入是我一直试图弄清楚的。
    • @zfac122 更新了一个如何实现的示例。
    猜你喜欢
    • 1970-01-01
    • 2019-10-03
    • 2018-03-09
    • 1970-01-01
    • 2013-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多