0

我正在尝试解析文本文件的行,然后将它们存储在vector<string>. 我来自 Java 背景,对 C++ 如何处理将内容分配给缓冲区的值感到困惑。这是我的代码:

string line;
vector<string> adsList;
ifstream inputFile;
inputFile.open("test.txt");
while(getline(inputFile, line))
{
    adsList.push_back(line);
}

在 Java 中,当向数据结构添加对象时,会创建对象的副本,然后插入该副本。在 C++ 中,我的理解是数据结构只保存引用,因此任何操作都非常快。在 C++ 中实现我想要做的事情的正确方法是什么?我还尝试了以下代码:

vector<string> adsList;
string line;
ifstream inputFile;
inputFile.open("test.txt");
while(getline(inputFile, line))
{
    string *temp = new string;
    *temp = line;
    adsList.push_back(*temp);
}

我的理由是,创建一个新的字符串对象并存储它会在每次循环迭代被销毁后保留它。C++ 似乎处理这个与 Java 完全相反的问题,我很难理解它。

编辑:这是 test.txt 的样子:

item1 item1 item1
item2 item2 item2
item3 item3 item3
item4 item4 item4

我试图将每一行存储为一个字符串,然后将字符串存储在我的向量中。所以向量的前面会有一个值为“item1 item1 item1”的字符串。

4

4 回答 4

2

push_back()制作副本,因此您的第一个代码示例完全符合您的要求。事实上,所有 C++ 结构都默认存储副本。您必须有一个指针容器才能获取副本。

于 2012-11-26T05:22:29.723 回答
1

由于您没有发布整个代码,我建议您试试这个,看看它是否正在读取文件:

#include <iostream>
#include <fstream>
#include <vector>
using namespace std;

int main() {
  fstream inputFile("test.txt",fstream::in);
  string l;
  vector<string> v;
  while(getline(inputFile,l)) v.push_back(l);
  //Display the content of the vector:
  for(int i = 0; i < v.size(); ++i) {
    cout << v[i] << endl;
  }
  return 0;
}
于 2012-11-26T05:22:41.060 回答
1

您对引用的理解不正确-Java 存储引用,C++ 存储您要求的任何内容,无论是它pointers还是copies(请注意,您不能将引用存储在 stl 容器中,等价于指针)

vector::push_back存储存储在向量中的项目的副本- 因此您不必在堆上创建pointer, 和new一些内存来存储字符串。

(在内部,有一些堆分配正在进行,但这是实现细节std::string

我们在 C++ 中的选项store pointers,而这些你必须堆分配,否则当当前堆栈帧被弹出时,指针将指向失效的内存......但这是另一个话题。

有关代码的简单工作示例,请参见此处:

#include <iostream>
#include <vector>
#include <fstream>

int main()
{
    std::vector<std::string> adsList;
    std::string line;
    std::ifstream inputFile;
    inputFile.open("test.txt");

    // read a line from the file - store it in 'line'
    while(getline(inputFile, line))
    {
        // store a *copy* of line in the vector
        adsList.push_back(line);
    }

    // for each element in adsList vector, get a *reference* (note the '&')
    for (std::string& s : adsList)
    {
        std::cout << s << std::endl;
    }

    exit(0);
}
于 2012-11-26T05:22:59.367 回答
1

你最初的假设是不正确的。副本(通常)存储在vector(忽略使用 C++11 引入的移动操作)。通常,这是您想要的操作方式。

如果您真的担心速度并且想要存储对事物的引用(实际上是指针),您将需要使用类似std::unique_ptror的东西std::shared_ptr。例如:

std::vector<std::unique_ptr<std::string>> adsList;
std::string line;
inputFile.open("test.txt");
while(std::getline(inputFile, line)) {
    adsList.push_back(std::unique_ptr<std::string>(new std::string(line));
}

通常,仅当您必须能够修改容器中的值并将修改反映到原始对象时才会这样做 - 在这种情况下,您将使用std::shared_ptr. 到目前为止,最常见的场景是您的第一个代码示例。

于 2012-11-26T05:23:54.757 回答