如何在C ++中将本地字符串数组复制到私有成员字符串数组?

时间:2017-10-26 07:07:56

标签: c++ arrays string

我正在尝试编写一个行读取器来填充一个字符串数组,该数组是同一个类的私有成员。我希望构造函数调用的loader函数动态调整成员数组的大小并填充它。这没有用。然后我设法在loader函数中填充本地数组。但我无法将这些值复制给班级的私人成员。

我认为必须有一种方法可以从本地" ReadLines"数组到类私有成员"行"阵列。

我已经阅读过内部如何实现vector类。但我仍然认为动态填充字符串数组必须通过其他一些简单方式实现,类似于我在Read()函数中调整本地数组的大小。

我在网上搜索,但没有标准或自我实现的矢量类,找不到任何答案。在矢量(如果有的话)完全忘记之前有旧方法吗?矢量类是神奇的吗?

除了矢量之外还有其他方法吗?

linereader.h:

class LineReader
{
    public:
        LineReader();
        void Read();

    private:
        string Lines[];
        int LineCount;
};

linereader.cpp:

#include <string>
#include <iostream>
using namespace std;
#include <fstream>
#include "linereader.h"

LineReader::LineReader()
{
    Read();
    cout << "Line Count : " << LineCount << endl;
    cout << "Lines Size : " << sizeof(Lines) << endl;
    cout << "Lines 0 : ";
    cout << Lines[0] << endl; //Gives segmantation fault
}

void LineReader::Read()
{
    std::ifstream infile("lines.txt");

    string *ReadLines = new string[1];

    string line;
    int linenumber = 0;
    while (infile >> line)
    {
        cout << endl << linenumber << " :: " << line << " ";

        string* temp_Lines = new string[linenumber + 1];
        for(int i = 0; i < linenumber; i++){
            cout << i << ",";
            temp_Lines[i] = ReadLines[i];
        }
        cout << "[" << linenumber << "]";

        delete [] ReadLines;
        ReadLines = temp_Lines;
        ReadLines[linenumber] = line;
        linenumber++;
    }
    infile.close();
    cout << endl << "----------------------------------" << endl;
    cout << "ReadLines Count : " << linenumber << endl;
    LineCount = linenumber;

    for(int i = 0; i < linenumber; i++){
        cout << "ReadLines "<< i + 1 << " " << ReadLines[i] << endl;
    }

    /////////////////////////////////////
    //       HERE IS THE PROBLEM       //
    // how to copy ReadLines to Lines? //
    /////////////////////////////////////
    //string *Lines = new string[linenumber + 1]; //  FLOODING TERMINAL WITH EMPTY LINES
    //   Lines =   ReadLines;   //  not working
    //   Lines =  *ReadLines;   //  error: cannot convert
    //   Lines = **ReadLines;   //  error: no match for ‘operator*’
    //  *Lines =   ReadLines;   //   error: invalid conversion from
    //  *Lines =  *ReadLines;   //  FLOODING TERMINAL WHEN RUN
    //  *Lines = **ReadLines;   //  error: no match for ‘operator*’
    // **Lines =   ReadLines;   //  error: no match for ‘operator*’
    // **Lines =  *ReadLines;   //  error: no match for ‘operator*
    // **Lines = **ReadLines;   //  error: no match for ‘operator*
}

int main(int argc, char* argv[])
{
    LineReader linereader;
    return 0;
}

lines.txt:

AAA
BBB
CCC
DDD
EEE
FFF
GGG

汇编:

g++ linereader.cpp -o linereader 

输出:

0 :: AAA [0]
1 :: BBB 0,[1]
2 :: CCC 0,1,[2]
3 :: DDD 0,1,2,[3]
4 :: EEE 0,1,2,3,[4]
5 :: FFF 0,1,2,3,4,[5]
6 :: GGG 0,1,2,3,4,5,[6]
----------------------------------
ReadLines Count : 7
ReadLines 1 AAA
ReadLines 2 BBB
ReadLines 3 CCC
ReadLines 4 DDD
ReadLines 5 EEE
ReadLines 6 FFF
ReadLines 7 GGG
Line Count : 7
Lines Size : 0
Segmentation fault

2 个答案:

答案 0 :(得分:0)

尝试从main函数调用read。那么修改私有值应该没有问题。

如果还要在主文件中添加打印功能,则可以将以下代码添加到linereader.cpp中,注意构造函数现在是一个空实现。

ineReader::print()
{
    cout << "Line Count : " << LineCount << endl;
    cout << "Lines Size : " << sizeof(Lines) << endl;
    cout << "Lines 0 : ";
    cout << Lines[0] << endl; //Gives segmantation fault
}

LineReader::LineReader() { }

int main(int argc, char* argv[])
{
    LineReader linereader;
    linereader.read();
    linereader.print();
    return 0;
}

答案 1 :(得分:0)

问题在于:

string Lines[];

您声明一个空数组。更准确地说,您声明了一个不完整的数组,该数组通常实现为0大小的数组。这就是行Lines Size : 0表示的内容。当你在已经分配了数组内存的地方创建一个对象时,它(主要是在C中)使用它,并且只作为结构或类的最后一个元素 - 简而言之,永远不要在你自己的代码中使用它。它应该至少引发一个警告,因为它不是该类的最后一个元素。

但是一旦你以这种方式宣布它,就什么也做不了。恕我直言的方式是声明指针的方式不太好:因为你已经知道了以下成员的长度就够了:

private:
    string *Lines;
    int LineCount;

然后你可以安全地做到:

Lines =   ReadLines;

但你所做的就是接近无意义。您可以避免使用(经过良好优化且经过良好测试的)矢量对象来进行数组的分配,复制和释放。这意味着您的代码将提供比使用向量更低效的程序。另外,由于C ++没有垃圾收集,这段代码很可能会破坏堆。

换句话说,在探索低级构造方面没有什么不好,但请注意,这个构造应该永远不会出现在生产代码中。