简体   繁体   English

永久存储缓冲区值

[英]Permanently storing a buffer value

I'm trying to parse the lines of a text file and then store them inside of a vector<string> . 我试图解析文本文件的行,然后将其存储在vector<string> I'm coming from a Java background and am confused on how C++ handles assigning stuff to the value of a buffer. 我来自Java背景,对C ++如何处理将内容分配给缓冲区的值感到困惑。 Here is my code: 这是我的代码:

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

In Java, when adding to a data structure a copy of the object is made and then that copy is inserted. 在Java中,将对象复制到数据结构中后,将其插入。 In C++, my understanding is that the data structures only hold references so that any operation is very fast. 在C ++中,我的理解是数据结构仅包含引用,因此任何操作都非常快。 What is the proper way to achieve what I want to do in C++? 什么是实现我要在C ++中完成的正确方法? I have also tried the following code: 我还尝试了以下代码:

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);
}

With my reasoning here being that creating a new string object and storing that would preserve it after being destroyed each loop iteration. 我的理由是创建一个新的字符串对象并进行存储,在每次循环迭代被销毁后将保留它。 C++ seems to handle this completely opposite of Java and I am having a hard time wrapping my head around it. C ++似乎可以解决Java的完全相反的问题,我很难解决这个问题。

edit: here is what test.txt looks like: 编辑:这是test.txt的样子:

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

I'm trying to store each line as a string and then store the string inside my vector. 我试图将每行存储为一个字符串,然后将字符串存储在我的向量中。 So the front of the vector would have a string with value "item1 item1 item1". 因此,向量的前面将有一个值为“ item1 item1 item1”的字符串。

push_back() makes a copy, so your first code sample does exactly what you want it to do. push_back()会进行复制,因此您的第一个代码示例将完全按照您的要求执行。 In fact, all C++ structures store copies by default. 实际上,默认情况下,所有C ++结构都存储副本。 You'd have to have a container of pointers to not get copies. 您必须具有一个指针容器才能不获取副本。

Since you didn't post the entire code, I suggest you try this to see if it is reading the file: 由于您没有发布完整的代码,因此建议您尝试一下以查看其是否正在读取文件:

#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;
}

Your understanding re references is incorrect - Java stored references, C++ stores whatever you ask it to , be it pointers or copies (note you can't store references in stl containers, the equivalent is pointers) 您对重新引用的理解是不正确的-Java存储的引用,C ++存储您要求的内容,无论是pointers还是copies (请注意,您不能将引用存储在stl容器中,等效于指针)

vector::push_back stores a copy of the item being stored in the vector - so you don't have to create a pointer , and new some memory on the heap in order to store the string. vector::push_back存储项目的副本存储在矢量-所以你不必创建一个pointer ,而new以存储字符串堆上一些内存。

(Internally, there is some heap allocation going on, but that's implementation details of std::string ) (在内部, 一些堆分配回事,但是这是实现细节std::string

What option we do have in C++ is to rather store pointers , and these you have to heap allocate, otherwise when the current stack frame is popped off, the pointers will be pointing to defunct memory... but that is another topic. 在C ++中,我们要做的是存储pointers ,而这些pointers 必须进行堆分配,否则当弹出当前堆栈帧时,指针将指向已失效的内存...但这是另一个主题。

See here for a simple working example of your code: 请参阅此处以获取代码的简单工作示例:

#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);
}

Your initial assumption is incorrect. 您最初的假设是不正确的。 A copy is (generally) stored in vector (ignoring move operations which were brought in with C++11). 通常将副本存储在vector (忽略C ++ 11带来的移动操作)。 Generally, this is the way you want to be operating. 通常,这是您要进行操作的方式。

If you are truly worried about speed and want to store references (pointers, actually) to things, you'll want to utilize something like std::unique_ptr or std::shared_ptr . 如果您真的担心速度,并且想存储对事物的引用(实际上是指针),则可以使用std::unique_ptrstd::shared_ptr For example: 例如:

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));
}

Generally this is only done if you must be able to modify the values in the container and have the modifications reflected to the original object - in this case you'd use a std::shared_ptr . 通常,只有在您必须能够修改容器中的值并将修改内容反映到原始对象上时,才执行此操作-在这种情况下,您将使用std::shared_ptr By far the most common scenario is your first code example. 到目前为止,最常见的情况是您的第一个代码示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM