【问题标题】:I cannot pass the data from my text file to my queue我无法将文本文件中的数据传递到队列
【发布时间】:2021-03-05 08:13:22
【问题描述】:

我正在创建一个程序,它将存储我的文本文件中的数据并将其排入队列。我已经为它创建了一个函数,但是它不会将数据存储到我的队列中。

这是我从文本文件中获取数据并将其插入队列的函数:

void TextToQueue() {
    Queue<Information> link; //Connecting my Queue to my structure called Information
    Information TextInfo; //Information is a structure containing string Name, Address, and ID
    Temp_File t; //Temp_File is a structure containing string data and type.
    fstream FILE;
    int i = 0;
    char delimiter = ':';
    char delimiter1 = '\n';
    FILE.open("Sample.txt", ios::in);
    if (FILE.is_open()) {
        while (getline(FILE, t.type, delimiter) && getline(FILE, t.data, delimiter1)) {
            if (i == 0) { 
                TextInfo.Name = t.data; //The data inside my t.data will be stored in TextInfo.Name
                i++;
            }
            else if (i == 1) {
                TextInfo.Address = t.data; //The data inside my t.data will be stored in TextInfo.Address
                i++;
            }
            else if (i == 2) {
                TextInfo.ID = t.data; //The data inside my t.data will be stored in TextInfo.ID
                link.push(TextInfo); //Pushing or Enqueuing the data to my queue
                i = 0; //the value of i will become zero again to repeat the whole process whenever there are a lot of data inside the file.
            }
        }
        FILE.close();
    }
    else {
        std::cout << "File is not open.";
    }
}

这是我将数据存储到队列的推送功能。每当我将新数据插入文本文件时,推送功能都会起作用,但是我认为问题出在 TextToQueue 函数中:

template <class T>
void Queue<T>::push(T data) {
    Queue* tmp = new Queue;
    tmp->value = data;
    tmp->next = NULL;
    if (!front) {
        rear = tmp;
        front = tmp;
    }
    else {
        rear->next = tmp;
        rear = tmp;
    }
}

【问题讨论】:

  • link.push(C_Info_LList)... 您在何时何地定义和初始化C_Info_LList 变量?为什么不推送你在函数中初始化的TextInfo
  • 抱歉。忘记完全编辑我的变量。坚持,稍等。发布此问题时,我更改了变量名称。
  • 这是您应该尝试创建正确的minimal reproducible example 的原因之一,您自己尝试确保它在发布之前复制问题。
  • 另外,你在TextToQueue 函数中定义了local 变量link。该变量的生命周期将在函数结束时结束,并且您推送给它的所有数据都将丢失。您应该返回队列,还是修改名称为 link 的成员或全局变量?
  • 我们不需要完整的课程。相反,请考虑何时何地定义 link 变量。正如我所说,它是函数内部的 local 变量。一旦函数返回变量link 消失,您添加到队列中的所有节点也将消失。也许您需要退后一步,重新了解变量范围和生命周期?

标签: c++ data-structures queue file-handling


【解决方案1】:

您的问题是循环和 if 语句的本地范围。每次将属性分配给Information 时,都会调用构造函数。解决方案是使用auto TextInfo = new Information 构造函数,推送它,然后将TextInfo 重新分配给一个新对象。只需要考虑销毁创建的对象。或者您可以将TextInfo 推送到队列中,然后只需修改属性并在最后一个子句中推送一个新的空白。

【讨论】:

    【解决方案2】:

    link 是一个不返回的局部变量。您无法从函数外部访问它。解决您的问题的一种方法是通过引用 TextToQueue 传递一个队列,将其填充到函数内部并在函数外部读取它:

    #include <fstream>
    #include <iostream>
    #include <string>
    
    template <class T>
    struct Queue {
        T value;
        Queue* front;
        Queue* rear;
        Queue* next;
        void push(T data);
    };
    
    template <class T>
    void Queue<T>::push(T data) {
        Queue* tmp = new Queue;
        tmp->value = data;
        tmp->next = NULL;
        if (!front) {
            rear = tmp;
            front = tmp;
        }
        else {
            rear->next = tmp;
            rear = tmp;
        }
    }
    
    struct Information {
        std::string ID;
        std::string Name;
        std::string Address;
    };
    struct Temp_File {
        std::string type;
        std::string data;
    };
    
    void TextToQueue(Queue<Information> &link) {
        Information TextInfo; //Information is a structure containing string Name, Address, and ID
        Temp_File t; //Temp_File is a structure containing string data and type.
        std::fstream FILE("Sample.txt", std::ios::in);
        int i = 0;
        char delimiter = ':';
        char delimiter1 = '\n';
        if (FILE.is_open()) {
            while (getline(FILE, t.type, delimiter) && getline(FILE, t.data, delimiter1)) {
                if (i == 0) { 
                    TextInfo.Name = t.data; //The data inside my t.data will be stored in TextInfo.Name
                    i++;
                }
                else if (i == 1) {
                    TextInfo.Address = t.data; //The data inside my t.data will be stored in TextInfo.Address
                    i++;
                }
                else if (i == 2) {
                    TextInfo.ID = t.data; //The data inside my t.data will be stored in TextInfo.ID
                    link.push(TextInfo); //Pushing or Enqueuing the data to my queue
                    std::cout << "push\n";
                    i = 0; //the value of i will become zero again to repeat the whole process whenever there are a lot of data inside the file.
                }
            }
            FILE.close();
        }
        else {
            std::cout << "File is not open.";
        }
    }
    
    int main() {
        Queue<Information> link; //Connecting my Queue to my structure called Information
        TextToQueue(link);
        std::cout << "Data: \n";
        std::cout << '"' << link.front->value.ID << "\"\n";
        std::cout << '"' << link.front->value.Name << "\"\n";
        std::cout << '"' << link.front->value.Address << "\"\n";
    }
    

    文件:

    id:ID
    name:Name
    address:Address
    

    输出:

    Data: 
    "Address"
    "ID"
    "Name"
    

    【讨论】:

    • 谢谢!有效!但是,我有一个问题。这可能是一个愚蠢的问题,但它将帮助我在未来更好地理解它。为什么我需要通过引用传递它?通过引用传递它与非引用相比有什么区别?
    • @Richard 按值传递会创建副本,但不会解决您的问题。您仍然会有两个不同的队列,一个在函数内部有数据,一个在函数外部没有数据。
    猜你喜欢
    • 2014-02-22
    • 1970-01-01
    • 1970-01-01
    • 2020-03-27
    • 1970-01-01
    • 2017-03-20
    • 2021-05-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多