我声明了一个char *数组char *excluded_string[50] = { 0 };
稍后excluded_string
数组的每个元素都会得到一个单词。现在我想把它转换成字符串,以便我可以将所有单词分隔成空格。
std::string ss(excluded_string);
会出错:
`server.cpp:171:32:错误:没有匹配的函数来调用'std :: basic_string :: basic_string(char * [50])'和大的棘手的解释!
答案 0 :(得分:12)
我声明了char * array char * excluded_string [50] = {0};
稍后ex_str数组的每个元素都会得到一个单词。现在我想把它转换成字符串,以便我可以将所有单词分隔成空格。
将其转换为单个字符串:
char *excluded_string[50] = { 0 };
// excluded_string filled in the meantime
std::ostringstream buffer; // add #include <sstream> at the top of
// the file for this
for(int i = 0; i < 50; ++i)
buffer << excluded_string[i] << " ";
std::string result = buffer.str();
编辑:注意事项:
如果可能的话,不要直接连接字符串:这将创建和销毁大量对象并执行大量不必要的分配。
如果您的代码具有严格的效率要求,请考虑事先分配/保留结果,以确保单次分配而不是重复分配。
如果连接字符串,请考虑使用operator + =而不是+和=。
编辑2:(回答评论)
如果+和=而不是+ =?
怎么办?
这里是串联字符串的两个备选方案的解析(s + = s1 + s2 vs s + = s1; s + = s2):
代码:
std::string ss;
for (int i=0; i<50; i++)
ss += std::string(excluded_string[i]) + " ";
等效代码(根据构造和分配的对象):
std::string ss;
for (int i=0; i<50; i++)
{
// ss += std::string(excluded_string[i]) + " ";
std::string temp1(excluded_string[i]); // "std::string(excluded_string[i])"
std::string temp2 = temp1 + " "; // call std::string operator+(std::string, char*)
ss += temp2; // call std::string::operator +=(std::string)
}
两个临时工都会创建数据副本(分配缓冲区,复制数据,释放缓冲区)。
代码:
std::string ss;
for (int i=0; i<50; i++)
{
ss += excluded_string[i]; // call std::string::operator +=(char*)
ss += " "; // same as above
}
std :: string :: operator + =被调用两次;它分配空间(如果需要),将字符串的当前内容复制到新分配的空间,然后在分配的缓冲区末尾复制新数据。
单个预先分配的空间:
预先分配/保留结果以确保单个分配
std::size_t total_length = 0;
for(int i = 0; i < 50; ++i)
total_length += std::strlen(excluded_strings[i]); // assumes argument is not null
std::string ss;
ss.reserve(total_length + 51); // reserve space for the strings and spaces between
for (int i=0; i<50; i++)
{
ss += excluded_string[i]; // calls std::string::operator +=
ss += " "; // same as above
}
在这种情况下,operator + =不在内部分配空间,只是在开始时(单个操作)。这仍然有点慢,因为你遍历字符串两次(0-> 49)并在每个字符串上迭代两次(一次计算长度,一次将其复制到ss)。
如果您的excluded_string是std :: vector,那么它会更有效率,因为计算字符串长度不会迭代每个字符串,只迭代矢量)。
答案 1 :(得分:3)
由于您小心地将指向c_str的指针数组初始化为0,因此我们可以使用该知识仅添加实际分配的单词:
此外,您需要先使用原始c_str构建一个std :: string,然后才能使用连接operator+
。
std::string stringResult;
for (int i=0; i!=50; ++i)
if(excluded_string[i])
{
stringResult.append(std::string(excluded_string[i]) + " ");
}
excluded_string
对象的类型是一个50个指向char 的指针的静态数组。所有指向char的指针都被代码初始化为0。
指向char的指针可以称为 C string ,或者更简洁地称为 c_str 。
C ++ STL为您提供std::string
类,several constructors are defined。其中一个使用 c_str (即指向char的指针)初始化字符串(迂腐地将其转换为指向const char的指针,这是此表达式中的隐式转换)。
这个构造函数是我们在编写时在解决方案中使用的构造函数:
std::string(excluded_string[i])
但正如您所看到的,没有构造函数采用 c_str 的数组,这正是编译器错误告诉您的。
编辑:措辞,感谢轨道中的轻盈竞赛评论。 ( cast 实际上意味着显式转换)。
答案 2 :(得分:2)
#include <iostream>
#include <string.h>
#include <algorithm>
#include <vector>
#include <sstream>
#include <iterator>
using namespace std;
int main()
{
char *arr[10] = {0};
for(int i = 0; i < 10; i++)
arr[i] = "wang";
ostringstream str;
copy(arr, arr+10, ostream_iterator<string>(str, " "));
cout<<str.str()<<endl;
}
答案 3 :(得分:1)
尝试循环:
std::string ss;
for (int i=0; i < 50; i++)
ss += std::string(excluded_string[i]) + " ";
您处于最佳状态的代码会将第一个字符串放入ss
。