Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在不复制的情况下从stringstream中提取字符?_C++_C++11_Stringstream - Fatal编程技术网

C++ 如何在不复制的情况下从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,

在不使用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, count);
    std::string str(buffer);  // Second copy performed here
    delete buffer;
    return str;
}
  • 我是否应该根据c++11使用char*缓冲区
  • 我怎样才能做第二份
  • 我的理解是向量初始化每个字符,所以我想避免这种情况

    此外,还需要将其传递到一个接受const char*的函数中,因此在运行该函数之后,我必须执行一个.c_str()。这也可以复制吗

    能够传回一个const char*会很好,但这似乎与“正确的”c++11风格背道而驰

    为了理解我正在尝试做什么,以下是我想“有效地”使用它的目的:

    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;i
    R萨胡,我喜欢这个!很明显,现在我看到它完成了

    我确实有一个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");