如何将字符串(来自n行文件)存储在初始化为唯一指针的动态数组中?C++

How can I store a string(from a file with n number of lines) in a dynamic array initialized as a unique pointer? C++

本文关键字:指针 唯一 初始化 动态 C++ 数组 存储 字符串 来自 文件      更新时间:2023-10-16

一名学生正在寻求指导。。。

这是一个课堂作业,包含以下说明:使用unique_ptr对象作为数据成员,重新编写程序"合唱列表"。您应该在unique_ptr对象中存储一个动态数组。使用此数组来存储、检索、删除和更新杂务。

我正在尝试了解更多关于使用unique_ptr对象的信息,以便创建用于初始化列表的构造函数。文本文件具有该列表,构造函数应将该列表存储到数组中。我正在尝试解决错误"读取位置访问冲突"。在原始程序中,我创建了一个容量更大的临时动态数组,并将列表复制到该数组中。文本文件中列出了10项家务。这是代码:

标题中:

private:
    /* var to keep len of list */
    int len = 0;
    int max = 9;
    /* add appropriate data structure to store list */
    string *arr = new string[max];

In.cpp:

/* reads the file line by line and initializes list */
ListOfChores::ListOfChores(string fileName){
    ifstream file(fileName, ifstream::in);
    string line;
        if (file.is_open()) //Checking if the file can be opened
        {
        while (getline(file, line)) // Gets a single line
        {
            if (len >= max)
            {
                string *narr = new string[max + 10]; // New, larger array
                for (int i = 0; i < max; i++)
                {
                    narr[i] = arr[i]; // Copies line
                }
                delete[] arr; // Clears
                arr = narr; // Copies
                max += 1; // Growth
            }
            arr[len] = line; // Store a line in the array
            len++; // Increases length by 1
        }
        file.close(); // Closes file
    }
    else cout << "Unable to open file" << endl;
}

为了表明我一直在努力,不是一个懒惰的学生。。。

新程序尝试标头:

private:
    /* var to keep len of list */
    int len = 0;
    int max = 9;
    /* add appropriate data structure to store list */
    string *arr = new string[max]; // Primary array
    string *narr = new string[max]; // New array

新程序.cpp:

/* reads the file line by line and initializes list */
ListOfChores::ListOfChores(string fileName) {
    unique_ptr<string[]> arr(new string[max]); // Unique pointer initialization
    ifstream file(fileName, ifstream::in);
    string line = " ";
    if (file.is_open()) //Checking if the file can be opened
    {
        while (getline(file, line)) // Gets lines from file
        {
            if (len >= max)
            {
                max++; // Growth
                unique_ptr<string[]> narr(new string[max]); // New unique pointer
                narr = move(arr);// narr owns the object
                narr[max] = line; // Store a line in the array
                len++; // Increases length by 1
                arr = move(narr); // arr owns the object
            }
            else
            {
                arr[len] = line; // Store a line in the array
                len++; // Increases length by 1
            }
        }
        file.close(); // Closes file
    }
    else cout << "Unable to open file" << endl;
}

unique_ptr的全部目的是在unique_ptr超出范围时销毁托管指针。这意味着您不希望在任何受限的范围内声明它。一旦退出当前代码块,您所做的任何工作都将被销毁。在函数内部创建但未返回给调用方的unique_ptr将消失,函数一返回,其内容也随之消失。如果您有一个用于存储动态数据量的类,那么应该在对象的范围内管理数据。

所以

private:
    /* var to keep len of list */
    int len = 0;
    int max = 20; // made bigger so first 50% increase is 10 elements
    /* add appropriate data structure to store list */
    std::unique_ptr<std::string[]> arr; // Primary array
    // no need for New array here

关于阵列大小增加50%还是100%更好的讨论可以在这里找到:动态分配阵列的理想增长率是多少?。和往常一样,你的里程数可能会有所不同,但一次增加一次通常被认为是个坏主意。

现在转到ListOfChores,在这里我们要使用但不声明unique_ptr

ListOfChores::ListOfChores(string fileName) {
    //no unique_ptr here. Scope is too narrow to be useful    
    ifstream file(fileName, ifstream::in);
    string line = " ";
    if (file.is_open()) //Checking if the file can be opened
    {
        while (getline(file, line)) // Gets lines from file
        {
            if (len >= max)// the current size is too small Let's make it bigger!
                           // if we grow before adding the line, we don't need any 
                           // special code to add the new line.
            {
                max *= 1.5; // Grow by 50%. Numerous studies have shown that 50% is a 
                            // good balance of RAM vs copy overhead in the general case
                std::string * narr = new string[max]; // no unique_ptr here either
                // old school copy for simplicity and obviousness
                for (int index = 0; index < len; index++)
                {
                     narr[index] = arr[index]
                } 
                arr.reset(narr); // frees and replaces the old array
                                 // arr now manages narr
            }
            // done growing, add normally to array 
            arr[len] = line; // Store a line in the array
            len++; // Increases length by 1
        }
        file.close(); // Closes file
    }
    else cout << "Unable to open file" << endl;
}

其他ListOfChores成员函数将使用arr,根据需要进行读取、加法和减法。为了有效地添加,应该从构造函数中删除数组增长代码,并将其放置在private方法中,以便由构造函数和其他需要扩大数组的方法调用。