C ++禁止从const char *设置char *和char []

时间:2011-07-17 20:11:56

标签: c++ char const

这是代码。我不知道为什么它不能识别它需要复制内存,我不能强迫它。

 string message="The quick brown fox jumped over the lazy dog.";

  vector<char*> words;

  while(message.length()>0){
    char wtf[message.substr(0,message.find(" ")).c_str().length()]=message.substr(0,message.find(" ")).c_str();
    words.push_back(wtf);
    message=message.substr(message.find(" ")+1);
  }

我看到有类似的线程,但没有。此外,C ++似乎无法轻易解决这个问题。

6 个答案:

答案 0 :(得分:6)

您希望按空格将字符串拆分为标记。您应该使用适当的工具 - 例如Boost.Tokenizer。您的代码在几个方面有误:

  1. 您无法定义类似的数组,维度必须是编译时常量表达式。
  2. 数组不是指针,也不能分配给数组。
  3. 只要字符串对象有效,
  4. c_str就会返回一个有效的指针。
  5. 除非您需要,否则请勿使用char*。使该向量保持std::string
  6. c_str返回char*,其中没有length成员函数或任何成员函数。
  7. 这表明你在C ++中缺乏一些基本的知识。您应该阅读a good book on C++。所以,不,这不是C ++的缺点。

    真的,只需使用Boost.Tokenizer。它有一个按文档中的空格分割的例子。

答案 1 :(得分:6)

如何将文字分解为单词(简单方法)

#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
#include <iterator>

int main()
{
    std::string message="The quick brown fox jumped over the lazy dog.";

    std::vector<std::string>    words;

    std::stringstream   stream(message);                  // 1: Create a stream
    std::copy(std::istream_iterator<std::string>(stream), // 2: Copy words from the stream
              std::istream_iterator<std::string>(),
              std::back_inserter(words));                 //    into the back of the vector.
}

分解它是如何工作的(对于12岁的学习编程)

  • 运营商&gt;&gt;当应用于流(和字符串)时,读取单个(白色)空格分隔的单词。

    std::string message="The quick brown fox jumped over the lazy dog.";
    std::stringstream   stream(message);
    
    std::string  word;
    stream >> word; // Reads "The"
    stream >> word; // Reads "quick"
    stream >> word; // Reads "brown" etc...
    
  • istream_iterator是流的适配器,使它们看起来像容器 它使用运算符&gt;&gt;

    从“T”类型的流中读取项目
    std::stringstream   stream("The quick brown fox jumped over the lazy dog.");
    std::istream_iterator<std::string> i(stream);
    
    std::string  word;
    
    word = *i;      // de-reference the iterator to get the object.   Reads "The"
    ++i;
    word = *i; ++i; // Reads "quick"
    word = *i; ++i; // Reads "brown" etc
    
    // Works for any type that uses >> to read from the stream 
    std::stringstream   intstream("99 40 32 64 20 10 9 8 102");
    std::istream_iterator<int> i(stream);  // Notice the type is int here
    
    int   number;
    
    number = *i;      // de-reference the iterator to get the object.   Reads "99"
    ++i;
    number = *i; ++i; // Reads "44"
    number = *i; ++i; // Reads "32" etc
    
  • 标准算法都适用于迭代器 std :: copy遍历源并将每个项目放在目标中:

    int    src[] = { 1, 2, 3, 4, 5, 6 };
    int    dst[] = { 0, 0, 0, 0, 0, 0 };
    
    std::copy(src, src+6, dst); // copies src into dst
                                // It assumes there is enough space in dst
    
  • back_inserter是一个使用push_back将项添加到容器的适配器 我们可以确保目标向量的大小正确。但是使用back_inserter更容易确保向量的动态大小。

    int    src[] = { 1, 2, 3, 4, 5, 6 };
    std::vector<int> dst; // Currently has zero size
    
    std::copy(src, src+6, std::back_inserter(dst)); // copies src into dst
                                                    // back_inserter expands dst to fit
                                                    // by using push_back
    
  • 全部重新组合:

    // Create a stream from the string
    std::stringstream   stream(message);
    
    // Use std::copy to copy from the string.
    //     The stream is iterated over a word at a time.
    //     because the istream iterator is using std::string type.
    //
    //     The istream_iterator with no parameters is equivelent to end.
    //
    //     The destination appends the word to the vector words.
    std::copy(std::istream_iterator<std::string>(stream), // 2: Copy words from the stream
              std::istream_iterator<std::string>(),
              std::back_inserter(words));                 //    into the back of the vector.
    

答案 2 :(得分:1)

string的{​​{1}}方法返回一个新的临时字符串,而substr方法将指针返回到该临时字符串的内存中。 简单地说,将指针放入临时缓冲区会导致未定义的行为。 如果您想保留子字符串,请改用c_str类。 string

答案 3 :(得分:0)

你想要数组中单词的副本,还是指向原始单词的指针?

如果你想要副本,那么你需要一个字符串向量。

此代码将创建单词的副本:

vector<string> words;
string::iterator it1 = message.begin();
string::iterator it2 = find(message.begin(), message.end(), ' ');
while (it2 != message.end())
{
    words.push_back(string(it1, it2));
    it1 = ++it2;
    it2 = find(it2, message.end(), ' ');
}
words.push_back(string(it1, it2));

此代码将指导原始单词:

vector<char*> words;
string::iterator it1 = message.begin();
string::iterator it2 = find(message.begin(), message.end(), ' ');
while (it2 != message.end())
{
    words.push_back(&*it1);
    it1 = ++it2;
    it2 = find(it2, message.end(), ' ');
}
words.push_back(&*it1);

答案 4 :(得分:0)

OMG

char *message="The quick brown fox jumped over the lazy dog.";

vector<char*> words;

int p=0;
while(message[p])
{
 words.push_back(&message[p++]);
}

//if you Must use a string, change to 
words.push_back(&message.c_str()[p++]);

这就是假设你想要指向每个角色的指针(我不知道你为什么会这样,但那就是你编码的那些)。

你想做什么BTW?

答案 5 :(得分:0)

通常,您只需使用vector<string>。作为C ++中的一般规则,看到原始指针是一个巨大的警告信号 - 要么使用智能指针并动态分配内存,要么使用值类型 - 例如std::string