永久存储缓冲区值

时间:2012-11-26 05:13:43

标签: c++

我正在尝试解析文本文件的行,然后将它们存储在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 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分: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;
}

答案 2 :(得分:1)

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

vector::push_back存储了存储在向量中的项目的副本 - 因此您无需创建pointernew一些内存在堆上以存储字符串。

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

我们在C ++中的选项是存储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);
}

答案 3 :(得分:1)

您的初步假设不正确。副本(通常)存储在vector中(忽略随C ++ 11引入的移动操作)。通常,这是您希望操作的方式。

如果您真的担心速度并希望将引用(实际指针)存储到事物中,那么您将需要使用std::unique_ptrstd::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。到目前为止,最常见的情况是您的第一个代码示例。