无法将 C 样式字符串推入 std::vector
Cannot push C style strings into std::vector
我正在尝试将一些 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
的类型更改为向量并推回 line
而不是 line.c_str()
,我将得到预期的输出:
dictionary[0] is Hello
dictionary[1] is World
dictionary[2] is Foo
dictionary[3] is Bar
我不是很熟悉 C 风格的字符串,所以它可能与空终止有关?
您正在存储悬挂指针。
std::string::c_str()
不是指向某个永久数据副本的指针 — 想想看,那会被泄露!
改为存储 std::string
。
您的代码调用了未定义的行为,因为在您这样做之后
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;
}
我正在尝试将一些 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
的类型更改为向量并推回 line
而不是 line.c_str()
,我将得到预期的输出:
dictionary[0] is Hello
dictionary[1] is World
dictionary[2] is Foo
dictionary[3] is Bar
我不是很熟悉 C 风格的字符串,所以它可能与空终止有关?
您正在存储悬挂指针。
std::string::c_str()
不是指向某个永久数据副本的指针 — 想想看,那会被泄露!
改为存储 std::string
。
您的代码调用了未定义的行为,因为在您这样做之后
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;
}