1

我担心缓冲区溢出,我需要从派生自 std::istream 的类中取出一些字符。据我了解,没有我自己的 >> 运算符,无法直接从 istream 流式传输到 std::string。所以我正在考虑将内容流式传输到 char 数组,然后将其放入 std::string。这是一个简单的例子:

char CharArray[1000] = {0};
SomeIStream >> CharArray;
std::string StuffFromStream(CharArray);

但是,似乎没有办法知道 CharArray 不会溢出。流提取运算符将写入 chararray 是否有最大值?有什么方法可以检查有多少会被抢先提取?这一切都错了吗,有没有比这更好的方法?

Edit1:,我修复了我的不是内存泄漏。无需调用删除。我不敢相信我做到了。

Edit2:建议直接使用 >> 到字符串。我在代码库中尝试过这个问题的来源,但它失败了。说找不到适合该运算符的匹配项。然后我尝试使用 std::fstream 并再次失败。在简单的简约项目中尝试 std::fstream 代码成功。这告诉我,我的大型项目还有其他问题。这个问题的初衷不再有效。

Edit3:我解决了这个问题。我试图流式传输到 typedef String,我认为它实际上是 std::string,但它实际上是一个 const std::String。自然没有用于写入不可写对象的流提取操作符,所以它只给了我 istream 标头中列出的所有操作符(我需要的是字符串标头中的操作符)。

感谢那些指出我的错误研究并指出我正确方向的人。

4

5 回答 5

3

如果你(正确地)从 std::istream 继承,那么你不需要做任何特别的事情,只需使用operator >> (std::istream&, std::string&).

std::string s;
SomeIStream >> s;

当我说“正确地”时,我的意思是从 istream 覆盖了适当的虚函数。

“我知道如果在删除之前出现异常,这会泄漏内存。” 不,不会的。你没有CharArray分配new; 调用delete它不会做你想做的事。

于 2010-12-15T21:36:30.137 回答
0

所有流都提供 .str() 方法,该方法将提供其缓冲区的副本作为 std::string (或 wstring 或其他类型定义的任何内容)。

此外,您在堆栈上声明了一个数组,然后尝试将其删除,即 UB。

于 2010-12-15T21:36:28.487 回答
0

如果要将整个流读入字符串,这不是非常有效,但很安全:

std::string str((std::istream_iterator<char>(some_istream)), std::istream_iterator<char>());

(注意额外的括号,以避免最麻烦的解析)

如果要读取最多“n”个字符:

some_istream.read(some_char_array, sizeof(some_char_array));

请注意,这不会以空值终止数组。sizeof(char_array) - 1如果您想保持数组的最后一个字符不变,请通过。

于 2010-12-15T21:40:07.670 回答
0

将老式 C 风格的字符数组与流混合?似乎是一些非常混乱的代码。

抛开注释不谈,直接提取成字符串即可。您可以将它(通过c_str()方法)传递给需要const char*参数的 C 样式 API。如果出于某种奇怪的原因你真的需要一个 char 数组,你可以在检查边界后安全地copy从char 数组。string

顺便说一句,您已经非常清楚地说明了幻数是邪恶的主要方式。在您的情况下,有问题的幻数是1000. 你不知道这1000是合适的——不要太大,也不要太小——没有完全猜测。在编程中,经常猜测 == 崩溃。或者更糟糕的是,不会崩溃。

顺便说一句,您在delete上面输入了一个自动变量。你不这样做。delete当且仅当您使用new. 你没有new,所以不要delete

顺便说一句,如果您只想将整个流提取到一个字符串中,您可以这样做:

string s = SomeIStream.str();
于 2010-12-15T21:33:05.550 回答
0

这就是我通常的方法(来自 Bruce Eckel 的“Thinking in C++”)::

ifstream in("somefile.txt",ios::in);
istreambuf_iterator isr(in),end;
字符串 str;
insert_iterator ins(str,str.begin());

而(istr!=结束){
      *ins++ = *istr++;
}

在上面的代码中,整个文件被当作一个字符流,然后放入一个字符串中。这仅作为示例显示。

于 2010-12-16T03:55:23.447 回答