C++ 如何在不复制的情况下从stringstream中提取字符?
在不使用boost的情况下,从stringstream中提取一组字符的正确c++11方法是什么 如果可能的话,我不想复制,因为在关键数据循环中使用它。不过,std::string似乎不允许直接访问数据 例如,下面的代码执行stringstream的子字符串复制:C++ 如何在不复制的情况下从stringstream中提取字符?,c++,c++11,stringstream,C++,C++11,Stringstream,在不使用boost的情况下,从stringstream中提取一组字符的正确c++11方法是什么 如果可能的话,我不想复制,因为在关键数据循环中使用它。不过,std::string似乎不允许直接访问数据 例如,下面的代码执行stringstream的子字符串复制: inline std::string left(std::stringstream ss, uint32_t count) { char* buffer = new char[count]; ss.get(buffer,
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;
}
fprintf( stderr, "Data: [%s]...", left(ststream, 255) );
但是c++11的力量:
fprintf( stderr, "Data: [%s]...", left(str_data, 255).c_str() );
我在这里复制了多少个字符串
如何将其简化为stringstream的单个副本?您可以使用此链接中描述的内容: 基本上,创建一个字符串,用传递给函数的大小对字符串调用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;
}
我的建议是:
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;
}
inline std::string left(std::stringstream ss,uint32\u t count){
std::string str(计数+1,'\0');
对于(uint32_t i=0;iR萨胡,我喜欢这个!很明显,现在我看到它完成了
我确实有一个mod(并且传递了一个共享的流,这是我在我的版本中实际拥有的):
在初始值设定项中,您正在填充null。您只需填写最后一个,因此我建议对此进行调整:
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;
}
inline std::string left(std::shared_ptr ss,uint32_t count){
std::字符串str;
str.reserve(计数+1);
uint32_t i;
对于(i=0;iget();
如果(c!=EOF){
str[i]=c;
}否则{
打破
}
}
str[i]='\0';
返回str;
}
现在,仅在单个字符上使用空值初始化
谢谢萨胡 如果此函数仅用于传递到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));
}
请记住,如果您稍后尝试在stringstream上使用流读取功能,则需要另一个seekg
;如果这与涉及str()
的选项的速度相同或更慢,我也不会感到惊讶。我还建议通过引用传入stringstream。我们不知道stringstream中数据的长度,复制如此多的数据本身可能是瓶颈。此外,我要注意的是,返回原子创建的变量应该移动字符串,而不是复制它,只要它是用c++11或等效标志编译的。但是,返回值永远不会被复制,因为每个编译器都会使用返回值优化。是的,我确实在流上使用了shared_ptr(只是在示例代码中没有这样做)。std::string str(buffer)代码>导致未定义的行为,缓冲区
不是空终止的。您是否考虑过按常量引用而不是按值传递ss
?这将消除一个拷贝。给出一个<代码>:ST::String 到<代码> fPrtuff>代码>是所有C++版本中的未定义行为。C++11没有改变这一点。另一个选项是%.255s
,带有参数str_data.str().C_str()
字符串类没有仅以整数作为参数的构造函数。您始终需要指定填充字符串的字符。当您可以仅使用引用时,为什么要添加共享\u ptr
?因为引用仍然会复制。我做了一些性能测试,在所有情况下,shared_ptr都能保证指针拷贝,但引用不能。在我的例子中,它保持内部执行副本。@user3072517通过引用传递不会复制stringstream或“内部执行副本”。你一定是误解了你在测试结果中看到的东西。所以在我的测试中,我实际上是在做一个类而不是一个字符串。我发现使用shared_ptr与const Class相比,性能有了巨大的提高。这个特殊的例行程序执行了100秒数百万次,时间增量非常显著。具体来说,在我杀死它之前,它从48秒到1100秒。
fprintf( stderr, "Data: [" );
left(stderr, stream, 255);
fprintf( stderr, "] ...\n");