我担心缓冲区溢出,我需要从一个派生自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头中列出的所有操作符(我需要的那个是在字符串头中)。
感谢那些指出我的错误研究并指导我正确方向的人。
答案 0 :(得分:3)
如果你(正确地)继承自std :: istream,那么你不需要做任何特殊的事情就可以使用operator >> (std::istream&, std::string&)
。
std::string s;
SomeIStream >> s;
当我说“正确”时,我的意思是从istream中覆盖适当的虚函数。
“我知道如果在删除之前有异常,这将泄漏内存。”不,不会。您没有使用CharArray
分配new
;在其上调用delete
将无法执行您想要的操作。
答案 1 :(得分:0)
将旧式C风格的char数组与流混合?看起来像一些非常混乱的代码。
除了评论之外,只需直接提取到字符串。您可以将其(通过c_str()
方法)传递给期望const char*
参数的C风格API。如果出于某种奇怪的原因你确实需要一个char数组,那么在检查边界之后,你可以安全地copy
从string
到char数组。
顺便说一句,你已经清楚地说明了magic numbers are evil的主要方式。在您的情况下,有问题的幻数是1000
。你不知道1000
是否恰当 - 不是太大,也不是太小 - 没有完全猜测。在编程中,猜测经常==崩溃。或者甚至更糟,不会崩溃。
顺便说一下,你是delete
上面的自动变量。你不这样做。当且仅当您使用delete
时,请使用new
。你没有new
,所以不要delete
。
顺便说一下3,如果您只想将整个流提取到字符串中,您可以这样做:
string s = SomeIStream.str();
答案 2 :(得分:0)
所有流都提供.str()方法,它将提供缓冲区的副本作为std :: string(或wstring或其他typedef的任何内容)。
此外,您在堆栈上声明了一个数组,然后尝试删除它,即UB。
答案 3 :(得分: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
。
答案 4 :(得分:0)
这就是我的做法(来自Bruce Eckel撰写的“Thinking in C ++”)::
ifstream in("somefile.txt",ios::in); istreambuf_iterator istr(in),end; string str; insert_iterator ins(str,str.begin()); while(istr != end){ *ins++ = *istr++; }
在上面的代码中,整个文件被视为一个字符流,然后放入一个字符串中。这只是一个例子。