无法将C风格的字符串推送到std::vector中

Cannot push C style strings into std::vector

本文关键字:std vector 字符串 风格      更新时间:2023-10-16

我正试图将一些const char*推送到向量中,但在执行了我认为要填充的操作后,向量仍然没有填充。

以下是我的尝试,dict是我的命令行参数。

test.cc

#include <iostream>
#include <string>
#include <vector>
#include <fstream>
using namespace std;
int main(int argc, char **argv) 
{
  ifstream dict;
  size_t dict_size;
  dict.open(argv[1]); // Dictionary
  vector<const char*> dictionary; 
  string line;
  getline(dict, line);
  while(!dict.fail()) {
    dictionary.push_back(line.c_str());
    getline(dict, line);
  }
  dict_size = dictionary.size();
  for(int i = 0; i < dict_size; i++)
      cout << "dictionary[" << i << "] is " << dictionary[i] << endl;
}

dict

Hello
World
Foo
Bar

编译后,我得到以下输出:

dictionary[0] is 
dictionary[1] is 
dictionary[2] is 
dictionary[3] is 

然而,如果我将dictionary的类型更改为vector,并将line而不是line.c_str()推回,我将得到预期的输出:

dictionary[0] is Hello
dictionary[1] is World
dictionary[2] is Foo
dictionary[3] is Bar

我对C风格的字符串不是很熟悉,所以也许它与null终止有关?

您正在存储悬挂指针。

std::string::c_str()不是指向某个永久数据副本的指针—想想看,那会被泄露的!

存储std::string s。

您的代码调用未定义的行为,因为在执行之后

dictionary.push_back(line.c_str());

在下一行,指针可能会被删除:

getline(dict, line); // line now is a different string

您正在将指向同一地址的指针推入字典,在最后一次迭代时,它会用空字符串填充内存区域。如果你不在乎内存泄漏,你可以这样尝试:

#include <iostream>
#include <string>
#include <vector>
#include <fstream>
using namespace std;
int main(int argc, char **argv) 
{
  ifstream dict;
  size_t dict_size;
  dict.open(argv[1]); // Dictionary
  vector<char *> dictionary; 
 while(!dict.fail()) {
 string * line = new string();
 getline(dict, *line);
 if(line->length()>0)
 {
   dictionary.push_back((char *)line->c_str());
 }
}
  dict_size = dictionary.size();
 for(int i = 0; i < dict_size; i++)
      cout << "dictionary[" << i << "] is " << dictionary[i] << endl;
}