使用https://stackoverflow.com/a/236803/6361644中提到的以下代码,我编写了以下代码来将字符串解析为向量,其中每个元素由空格分隔。
std::string line = "ls -l -a";
std::string cmd;
std::vector<char*> argv;
std::stringstream ss;
ss.str(line);
std::string tmp;
getline(ss, cmd, ' ');
argv.push_back( const_cast<char*>(cmd.c_str() ) );
while(getline(ss, tmp, ' '))
argv.push_back( const_cast<char*>(tmp.c_str() ) );
argv.push_back(NULL);
在此代码之后打印argv
{gdb) print argv
$22 = std::vector of length 3, capacity 4 = {0x26014 "ls", 0x2602c "-a", 0x2602c "-a", 0x0}
我不确定为什么要覆盖第二个元素。任何提示将不胜感激。
答案 0 :(得分:2)
你正在存储悬空指针(以不正确的方式存储!存储指向c风格字符串的指针的正确方法是const char*
,而不是char*
)。
在此(const
- 更正的)循环中:
std::vector<const char*> argv;
// ...
while(getline(ss, tmp, ' '))
argv.push_back(tmp.c_str());
每次后续迭代都将清除tmp
,使您存储的先前指针无效。您推回的每个tmp.c_str()
都会被getline()
立即释放。因此,所有后续访问都是未定义的。
你必须取得所有字符串的所有权,你可以通过存储完整的string
来实现这一点:
std::vector<std::string> argv;
// ...
while(getline(ss, tmp, ' '))
argv.push_back(std::move(tmp));
现在argv
实际上拥有自己的所有资源。
答案 1 :(得分:-1)
c_str()
返回的指针指向std::string
的内部数据。
此指针仅在字符串被销毁或修改之前有效。一旦std::string
被销毁或修改,指针就不再有效了。
while(getline(ss, tmp, ' '))
argv.push_back( const_cast<char*>(tmp.c_str() ) );
抛开抛出const
- ness的问题,这已经是一个红旗:每次while
循环迭代时tmp
的内容被下一行替换在ss
文件中。
这会自动使在c_str()
循环的上一次迭代中获得的while
无效。
这里正确的解决方案是首先将所有单个单词解析为std::vector<std::string>
。
然后,初始化此向量后,迭代向量并获取每个单独的字符串c_str()
,以构造原始字符指针的向量。
更好:使用std::vector<char>
代替std::string
,添加明确的&#39; \ 0&#39;每个向量末尾的字符,丑陋的const_cast
不是必需的。