【问题标题】:How deal with buffer overflow in C?如何处理 C 中的缓冲区溢出?
【发布时间】:2019-04-22 12:38:15
【问题描述】:

如果输入的长度大于2,为什么这段代码会多次跳过循环?

这似乎与缓冲区溢出有关。但是我可以在循环结束时清除输入缓冲区吗?如何?

#include <stdio.h>

int main(void)
{
    char in[2];
    while (in[0] != 'q') {
        puts("Enter: ");
        fgets(in, 3, stdin);
    }
    return 0;
}

我想要求用户在每个循环中输入一些字符串。

【问题讨论】:

  • 不是3,而是2 for fgets。缓冲区只有 2 大。
  • 你能给我看一些这个具体问题的例子吗?
  • 不,这与缓冲区溢出无关。这只是一个偶然。而且我不知道为什么有人认为这值得支持。您的问题是 fgets 如果行长于缓冲区,则不会跳过所有内容直到行尾。
  • 您告诉fgets,您的缓冲区足够大,可以容纳 2 个字符和一个空字符 ('\0')。但是你的缓冲区只够容纳 1 个字符加上 '\0'
  • 当输入长度超过1时,fgets尝试写入超出数组边界的数据。之后你的程序的行为是未定义的。

标签: c buffer fgets


【解决方案1】:

首先,您的缓冲区不够大,无法容纳 2 个字符的字符串。 C 中的字符串需要附加一个额外的 '\0' 来标记结束。其次,fgets 将在输入字符串长于传递给它的缓冲区时将字符留在输入缓冲区中。您需要在再次调用fgets 之前消耗这些字符。

这是一个函数,类似于fgets,它只会读取buffer_len - 1 字符。它还将消耗所有字符,直到换行符或 EOF。

int my_gets(char *buffer, size_t buffer_len)
{
    // Clear buffer to ensure the string will be null terminated
    memset(buffer, 0, buffer_len);

    int c;
    int bytes_read = 0;
    // Read one char at a time until EOF or newline
    while (EOF != (c = fgetc(stdin)) && '\n' != c) {
        // Only add to buffer if within size limit
        if (bytes_read < buffer_len - 1) {
            buffer[bytes_read++] = (char)c;
        }
    }
    return bytes_read;
}

int main(void)
{
    char in[3];  // Large enough for a 2 char string

    // Re-arranged to do/while
    do {
        puts("Enter: ");
        my_gets(in, sizeof(in));  // sizeof(in) == 3
    } while (in[0] != 'q');
    return 0;
}

【讨论】:

    猜你喜欢
    • 2012-02-05
    • 1970-01-01
    • 2011-09-07
    • 1970-01-01
    • 1970-01-01
    • 2013-09-16
    • 1970-01-01
    • 1970-01-01
    • 2015-12-26
    相关资源
    最近更新 更多