【问题标题】:Combining std::string and std::vector<char>结合 std::string 和 std::vector<char>
【发布时间】:2010-12-30 12:03:16
【问题描述】:

这不是实际的代码,但这代表了我的问题。

std::string str1 = "head";
char *buffer = "body\0body"; // Original code has nullbytes;
std::string str2 = "foot";
std::vector<char> mainStr(buffer, buffer + strlen(buffer));

我想将str1str2按顺序排列到mainStr

头身\0身脚

所以二进制数据被维护了。可以这样做吗?

PS:感谢您告诉strlen 部分错误。我只是用它来表示buffer 的长度。 :)

【问题讨论】:

  • 你想把它放在哪里?一个字符串,一个向量,一个流?
  • @Antonio Perez 我想把它放在mainStr 变量中,正如我所说的:)。这是std::vector&lt;char&gt;
  • 附带说明:为什么要使用std::vectorstd::string 也可以存储空字符。

标签: c++ string stl vector


【解决方案1】:

应该有一些方法来定义“缓冲区”中的数据长度。 通常字符 0 用于此,大多数标准文本函数都假定此。所以如果你将字符 0 用于其他目的,你必须提供另一种方法来找出数据长度。

举例:

char buffer[]="body\0body";
std::vector<char> mainStr(buffer,buffer+sizeof(buffer)/sizeof(buffer[0]));

这里我们使用数组,因为它提供了比指针更多的信息——存储数据的大小。

【讨论】:

  • +1 用于指出char buffer[]char buffer* 之间的区别,因为sizeof() 对它们的操作方式不同!
【解决方案2】:

您不能使用strlen,因为它使用'\0' 来确定字符串的结尾。但是,以下内容将满足您的需求:

std::string head = "header";
std::string foot = "footer";
const char body[] = "body\0body";

std::vector<char> v;
v.assign(head.begin(), head.end());
std::copy(body, body + sizeof(body)/sizeof(body[0]) - 1, std::back_inserter<std::vector<char> >(v));
std::copy(foot.begin(), foot.end(), std::back_inserter<std::vector<char> >(v));

因为字符缓冲区在字符串末尾添加了一个 NUL 字符,所以您需要忽略它(因此最后一个迭代器中的 -1)。

【讨论】:

    【解决方案3】:

    顺便说一句。如果您的字符串中有 nul 字节,strlen 将不起作用!

    要插入向量的代码是:

    正面:

    mainStr.insert(mainStr.begin(), str1.begin(), str1.end());
    

    返回:

    mainStr.insert(mainStr.end(), str2.begin(), str2.end());
    

    使用上面的代码(使用strlen 将打印)

    头身脚

    编辑:刚刚将copy 更改为insert,因为我认为copy 需要可用空间。

    【讨论】:

      【解决方案4】:

      您可以使用std::vector&lt;char&gt;::insert 将您需要的数据附加到mainStr

      类似这样的:

      std::string str1 = "head";
      char buffer[] = "body\0body"; // Original code has nullbytes;
      std::string str2 = "foot";
      
      std::vector<char> mainStr(str1.begin(), str1.end());
      mainStr.insert(mainStr.end(), buffer, buffer + sizeof(buffer)/sizeof(buffer[0]));
      mainStr.insert(mainStr.end(), str2.begin(), str2.end());
      

      免责声明:我没有编译它。

      【讨论】:

      • strlen 将在缓冲区的第一个空字节处停止
      【解决方案5】:

      您可以使用 IO 流。

      std::string str1 = "head";
      const char *buffer = "body\0body"; // Original code has nullbytes;
      std::string str2 = "foot";
      std::stringstream ss;
      ss.write(str1.c_str(), str1.length())
        .write(buffer, 9) // insert real length here
        .write(str2.c_str(), str2.length());
      std::string result = ss.str();
      
      std::vector<char> vec(result.c_str(), result.c_str() + result.length());
      

      【讨论】:

        【解决方案6】:

        str1 和 str2 是写入文本的字符串对象。

        我希望编译器在声明缓冲区这样的语句上会失败,我不在乎它破坏了多少遗留代码。如果您仍在构建它,您仍然可以修复它并放入一个 const。

        您需要更改向量的声明,因为 strlen 将在第一个空字符处停止。如果你这样做了

        char buffer[] = "body\0body";
        

        然后 sizeof(buffer) 实际上会给你接近你想要的东西,尽管你也会得到最后的空终止符。

        一旦你的向量 mainStr 设置正确,你可以这样做:

        std::string strConcat;
        strConcat.reserve( str1.size() + str2.size() + mainStr.size() );
        strConcat.assign(str1);
        strConcat.append(mainStr.begin(), mainStr.end());
        strConcat.append(str2);
        

        如果向量是使用缓冲区设置的,buffer+sizeof(buffer)-1

        【讨论】:

          【解决方案7】:
           mainStr.resize(str1.length() + str2.length() + strlen(buffer));  
           memcpy(&mainStr[0], &str1[0], str1.length());  
           memcpy(&mainStr[str1.length()], buffer, strlen(buffer));  
           memcpy(&mainStr[str1.length()+strlen(buffer)], &str2[0], str2.length());
          

          【讨论】:

            猜你喜欢
            • 2011-10-26
            • 1970-01-01
            • 2012-05-13
            • 2021-03-23
            • 2012-03-07
            • 2014-10-24
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多