【问题标题】:Using cin in C++ with Width() to avoid buffer overflow [closed]在 C++ 中使用 cin 和 Width() 来避免缓冲区溢出 [关闭]
【发布时间】:2012-01-07 01:43:16
【问题描述】:

这是一个简单的问题。我写了这段 C++ 代码:

    char chaine[12];
    cin.width(12);
    cin >> chaine;

但如果我在运行时输入一些超过 12 个字符的文本,Visual Studio 会通知我堆栈现在已损坏。

我知道问题是缓冲区溢出。但我认为“宽度”方法可以防止这种情况。

如果宽度方法不能防止缓冲区溢出,谁能向我解释一下它的功能是什么?我在网上搜索,但没有找到任何东西。

谢谢!

【问题讨论】:

  • 还有更多代码吗?这对我来说看起来不错。我看到的唯一问题是chaine 不会以零结尾,这可能会导致以后出现问题。
  • 你知道有更好的方法,对吧? std::string chaine; std::cin >> chaine;。无需担心缓冲区溢出。
  • 整个代码如下: int main () { char chaine[12]; cin.width(12); cin >> 链;返回0; }
  • @Phil:cHao 是对的。只需在 C++ 中使用 std::string
  • 是的。我知道改用“字符串”。但我也想了解这一点以及为什么它不起作用。

标签: c++ file io buffer-overflow


【解决方案1】:

该代码确实显然应该将输入限制为 11 个字符(第 12 个字符用于终止空字符)。该标准在 27.7.2.2.3 [istream::extractors] 第 7 和 8 段中明确规定:

... 如果 width() 大于零,则 n 为 width()。 ... 字符被提取和存储,直到发生以下任何情况: - n-1 个字符被存储; ...

我还尝试使用 gcc,它显然只能读取 11 个字符。我不知道这个问题的最佳解决方法是什么。通常,我不会遇到这样的问题,因为我只是简单地读取了std::string 对象,这些对象可以随心所欲地增长。好吧,也有一些巨大的限制,我从来没有尝试过当超过这个限制时会发生什么。如果您绝对需要读入 char 数组,您可以做两件事:

  1. 您可以为char 数组创建适配器并自己定义合适的输入运算符
  2. 您可以创建一个临时安装的过滤流缓冲区,它限制字符数或假装它读取空格字符。

以下是如何执行后者的示例。创建适配器的技术实际上可以用于根据数组的大小自动设置宽度。

#include <iostream>
#include <cctype>

struct adaptor
{
    template <int Size>
    adaptor(char (&array)[Size]): it(array), end(array + Size - 1) {}
    mutable char*  it, * end;
};

std::istream& operator>> (std::istream& in, adaptor const& value)
{
    std::istreambuf_iterator<char> it(in), end;
    if (it == end)
    {
        in.setstate(std::ios_base::failbit);
    }
    for (; it != end && value.it != value.end && !std::isspace(static_cast<unsigned char>(*it));
         ++it, ++value.it)
    {
        *value.it = *it;
    }
    *value.it = 0;
    return in;
}

int main()
{
    char buffer[12];
    if (std::cin >> adaptor(buffer))
        std::cout << "read='" << buffer << "'\n";
    else
        std::cout << "input failed\n";
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-19
    • 2018-07-26
    • 1970-01-01
    • 2020-01-26
    相关资源
    最近更新 更多