这是一个简单的问题。我写了这个C ++代码:
char chaine[12];
cin.width(12);
cin >> chaine;
但是如果我在运行时输入一些超过12个字符的文本,Visual studio告诉我堆栈现在已损坏。
据我所知,问题是缓冲区溢出。但我认为“宽度”方法可以防止这种情况发生。
有人可以向我解释一下宽度方法的功能是什么,如果它不能防止缓冲区溢出?我在网上搜索但我没有找到任何东西。
谢谢!
答案 0 :(得分:3)
这段代码确实应该将输入限制为11个字符(第12个字符用于终止空字符)。该标准明确载于27.7.2.2.3 [istream :: extractors]第7和第8段:
...如果width()大于零,则n为width()。 ...提取并存储字符,直到出现以下任何一种情况: - 存储n-1个字符; ...
我也尝试过gcc,它只能读取11个字符。我不知道这个问题最好的解决办法是什么。通常情况下,我不会遇到这样的问题,因为我简单地阅读std::string
对象,这些对象可以根据需要增长。好吧,还有一些巨大的限制,我从来没有尝试过这会超出的情况。如果您绝对需要阅读char
数组,您可以做两件事:
char
数组创建适配器并自己定义合适的输入运算符以下是如何做后者的示例。创建适配器的技术实际上可以用于根据数组的大小自动设置宽度。
#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";
}