在不使用boost的情况下从字符串流中提取一组字符的正确c ++ 11方法是什么?
如果可能的话,我想在没有复制的情况下这样做,因为使用它的地方是关键数据循环。但是,似乎std :: string不允许直接访问数据。
例如,下面的代码执行字符串流中的子字符串复制:
inline std::string left(std::stringstream ss, uint32_t count) {
char* buffer = new char[count];
ss.get(buffer, count);
std::string str(buffer); // Second copy performed here
delete buffer;
return str;
}
我的理解是矢量初始化每个角色,所以我想避免这种情况。
此外,这需要传递给一个接受const char *的函数,所以现在运行后我被迫做一个.c_str()。这也是副本吗?
能够传回一个const char *会很好,但这似乎违背了#34;正确的#34; c ++ 11风格。
为了理解我想要做什么,这里是"有效"我想用它来做什么:
fprintf( stderr, "Data: [%s]...", left(ststream, 255) );
但是c ++ 11强迫:
fprintf( stderr, "Data: [%s]...", left(str_data, 255).c_str() );
我在这里制作了多少份该字符串?
如何将其从字符串流中仅减少到一个副本?
答案 0 :(得分:8)
您可以使用此链接中描述的内容:How to create a std::string directly from a char* array without copying?
基本上,创建一个字符串,使用传递给函数的大小调用字符串上的resize()方法,然后将指针传递给stringstring.get()方法的字符串的第一个字符。您最终只能获得一份副本。
inline std::string left(std::stringstream& ss, uint32_t count) {
std::string str;
str.resize(count);
ss.get(&str[0], count);
return str;
}
答案 1 :(得分:2)
我的建议:
通过为其提供尺寸来创建要返回的std::string
。
从stringstream
逐一阅读字符,并在std::string
中设置值。
这是函数的样子:
inline std::string left(std::stringstream ss, uint32_t count) {
std::string str(count+1, '\0');
for (uint32_t i = 0; i < count; ++i )
{
int c = ss.getc();
if ( c != EOF )
{
str[i] = c;
}
else
{
break;
}
}
return str;
}
答案 2 :(得分:2)
我确实有一个mod(以及传递了我在我的版本中实际拥有的stream_ptr流):
在初始化程序中,您正在填充空值。你只需填写最后一个,所以我建议调整一下:
inline std::string left(std::shared_ptr<std::stringstream> ss, uint32_t count) {
std::string str;
str.reserve(count + 1);
uint32_t i;
for(i = 0; i < count; ++i) {
int c = ss->get();
if(c != EOF) {
str[i] = c;
} else {
break;
}
}
str[i] = '\0';
return str;
}
现在,只在单个字符上使用空值进行初始化。
谢谢R Sahu!
答案 3 :(得分:0)
如果此函数的目的仅仅是传递给fprintf
或另一个C风格的流,那么您可以通过执行以下操作来完全避免分配:
void left(FILE *out, std::stringstream &in, size_t count)
{
in.seekg(0);
char ch;
while ( count-- && in.get(ch) )
fputc(out, static_cast<unsigned char>(ch));
}
用法:
fprintf( stderr, "Data: [" );
left(stderr, stream, 255);
fprintf( stderr, "] ...\n");
请记住,如果您稍后尝试在字符串流上使用流读取功能,则需要另一个seekg
;如果这个速度与涉及str()
的选项相同或更慢,那就不会让我感到惊讶。