从文本文件读入数组结构

时间:2018-07-31 12:32:55

标签: c++ while-loop structure-of-arrays

我正在尝试将文本文件读入结构数组。我还没有找到一种将其输入到结构数组中的方法,但是我的代码的问题是输出不断循环。我是C ++的新手,因为这是我参加的第一门编程课程。

这是我放入的记录的文本文件,用“制表符”分隔。

1   Clark Kent  012-1449326 221, Jalan Pudu, Kuala Lumpur   clark_kent@gmail.com
2   Bruce Wayne 013-9817470 65, Jalan Jejaka, Kuala Lumpur  bruce_wayne@hotmail.com
3   Peter Parker 017-6912495    26, Jalan Rajabot, Kuala Lumpur peterparker@zoho.net
4   Yeoman Prince   014-1374040 22, Jalan 1/109e, Kuala Lumpur  yeoman_prince@yahoo.com
5   Tony Stark  016-7473151 21, Jalan Pandan, Kuala Lumpur  tonystark@zoho.net
6   Selina Kyle 012-4040928 Wisma Cosway, Kuala Lumpur  selina_kyle@gmail.com
7   Steve Rogers    018-9285217 Desa Pandan, Kuala Lumpur   steverogers@hotmail.com
8   Alan Scott  019-5569400 2, Jalan U1/17, Shah Alam   alanscott@gmail.com
9   Britt Reid  011-7876738 43, Jalan SS2/23, Petaling Jaya brittreid@yahoo.com
10  Darcy Walker    011-4042788 Blok B, Setapak, Kuala Lumpur   darcywalker@gmail.com
11  Reed Richards   019-2299339 Menara U, Bangsar, Kuala Lumpur reedrichards@zoho.net
12  Barbara Gordon  017-2297980 The Boulevard, Kuala Lumpur barbaragordon@gmail.com
13  Don Diego Vega  012-4142987 10, Jalan Wangsa, Kuala Lumpur  donvega@zoho.net
14  Billy Batson    013-9200151 122, Jalan Jejaka, Kuala Lumpur billybatson@hotmail.com
15  Barry Allen 017-7928822 Wisma Laxton, Kuala Lumpur  barryallen@gmail.com
16  Stanley Beamish 014-9177437 203, Sunwaymas, Batu Caves  stanleybeamish@yahoo.com
17  Dick Grayson    017-4023800 Pekeliling Bus, Kuala Lumpur    dickgrayson@hotmail.com
18  James Howlett   012-7816910 Sri Hartamas, Kuala Lumpur  jameshowlett@zoho.net
19  Hal Jordan  013-3439897 302, Jalan Ampang, Kuala Lumpur haljordan@yahoo.com
20  Scott Summers   012-9057100 Menara Summit, Subang Jaya  scottsummers@zoho.net

这是我的结构:

struct Employee {
int staffId;
char fullName[30];
char phoneNum[15];
char address[40];
char email[30];
};

函数读取:

int main(void) {
int choice;
int value = 0;
Employee data;
menu();

cin >> choice;
do {
    if (choice == 1) {
        read();
    }
    else if (choice == 2) {
        add(value, &data);
    }
    else if (choice == 3) {
        list(value, &data);
    }
    else if (choice == 4) {
        search();
    }
    else if (choice == 5) {
        update();
    }
    else if (choice == 6) {
        deletes();
    }
    else if (choice == 7) {
        exit();
    }
    else {
        cout << "\n **Invalid choice option. Please enter from numbers 1 to 7 : ";
        cin >> choice;
    }

} while (choice != 1 || choice != 2 || choice != 3 || choice != 4 || choice != 5 || choice != 6 || choice != 7);

return 0;

}

这是我读取文件的代码:

void process(string* line) {
    cout << "line read: " << *line << endl;
}

void read()
{
    string line;
    ifstream in("list.txt");

    if (!in.is_open()) {
        cerr << "File can't be opened! " << endl;
    }
    while(getline(in,line)) {
        process(&line);
    }

    if (in.bad()) {
        cerr << "File can't be read! " << endl;
    }
    in.close();
    return;
}

这是我的输出:

line read: 1    Clark Kent      012-1449326     221, Jalan Pudu, Kuala Lumpur   clark_kent@gmail.com
line read: 2    Bruce Wayne     013-9817470     65, Jalan Jejaka, Kuala Lumpur  bruce_wayne@hotmail.com
line read: 3    Peter Parker    017-6912495     26, Jalan Rajabot, Kuala Lumpur peterparker@zoho.net
line read: 4    Yeoman Prince   014-1374040     22, Jalan 1/109e, Kuala Lumpur  yeoman_prince@yahoo.com
line read: 5    Tony Stark      016-7473151     21, Jalan Pandan, Kuala Lumpur  tonystark@zoho.net
line read: 6    Selina Kyle     012-4040928     Wisma Cosway, Kuala Lumpur      selina_kyle@gmail.com
line read: 7    Steve Rogers    018-9285217     Desa Pandan, Kuala Lumpur       steverogers@hotmail.com
line read: 8    Alan Scott      019-5569400     2, Jalan U1/17, Shah Alam       alanscott@gmail.com
line read: 9    Britt Reid      011-7876738     43, Jalan SS2/23, Petaling Jaya brittreid@yahoo.com
line read: 10   Darcy Walker    011-4042788     Blok B, Setapak, Kuala Lumpur   darcywalker@gmail.com
line read: 11   Reed Richards   019-2299339     Menara U, Bangsar, Kuala Lumpur reedrichards@zoho.net
line read: 12   Barbara Gordon  017-2297980     The Boulevard, Kuala Lumpur     barbaragordon@gmail.com
line read: 13   Don Diego Vega  012-4142987     10, Jalan Wangsa, Kuala Lumpur  donvega@zoho.net
line read: 14   Billy Batson    013-9200151     122, Jalan Jejaka, Kuala Lumpur billybatson@hotmail.com
line read: 15   Barry Allen     017-7928822     Wisma Laxton, Kuala Lumpur      barryallen@gmail.com
line read: 16   Stanley Beamish 014-9177437     203, Sunwaymas, Batu Caves      stanleybeamish@yahoo.com
line read: 17   Dick Grayson    017-4023800     Pekeliling Bus, Kuala Lumpur    dickgrayson@hotmail.com
line read: 18   James Howlett   012-7816910     Sri Hartamas, Kuala Lumpur      jameshowlett@zoho.net
line read: 19   Hal Jordan      013-3439897     302, Jalan Ampang, Kuala Lumpur haljordan@yahoo.com
line read: 20   Scott Summers   012-9057100     Menara Summit, Subang Jaya      scottsummers@zoho.net
line read: 1    Clark Kent      012-1449326     221, Jalan Pudu, Kuala Lumpur   clark_kent@gmail.com
line read: 2    Bruce Wayne     013-9817470     65, Jalan Jejaka, Kuala Lumpur  bruce_wayne@hotmail.com
line read: 3    Peter Parker    017-6912495     26, Jalan Rajabot, Kuala Lumpur peterparker@zoho.net
line read: 4    Yeoman Prince   014-1374040     22, Jalan 1/109e, Kuala Lumpur  yeoman_prince@yahoo.com
line read: 5    Tony Stark      016-7473151     21, Jalan Pandan, Kuala Lumpur  tonystark@zoho.net

有什么方法可以建议它停止循环吗?我试图避免将大小设置为20,因为在程序的另一部分中,我应该添加更多的员工记录。所以,我的问题是:

  1. 如何阻止它无限循环?
  2. 如何将读取的行输入到结构数组中?

谢谢。

3 个答案:

答案 0 :(得分:1)

尝试此操作,逐行读取文件,然后根据定界符\t解析每一行。

void readFile(const string& filename) {
    ifstream ifs(filename);

    string line;
    while (getline(ifs, line)) {
        istringstream iss(line);
        string token;

        Employee emp;

        while (getline(iss, token, '\t')) {
            // if you just want to print the information
            cout << token << '\t';
            // or you can store it in an Employee object
            // ...
        }
        cout << endl;
    }
}

答案 1 :(得分:1)

问题是您从不要求用户提供新的菜单选项,因此您的程序陷入了首选状态,并无限循环。

您的循环应该看起来像这样,cin >> choice;循环内有do

do {
    cin >> choice;
    if (choice == 1) {
        read();
    }
    ...

通过此更改,您还需要重写错误处理逻辑,但我将留给您。

正如Bob__在下面的注释中所述,循环条件的逻辑是错误的choice != 1 || choice != 2 || choice != 3 || choice != 4 || choice != 5 || choice != 6 || choice != 7始终是真的,因此循环永远不会终止。

在任何情况下,您的整体程序逻辑中都存在多个错误,而这些是您在进入单个菜单项的功能之前应该解决的错误。

答案 2 :(得分:0)

问题的第二部分有点模糊。您是要向结构中输入数据,还是要创建employee类型的数组并将每个员工的数据放入该数组的索引中?无论哪种情况,我都会回答后者。

对于第一个问题,停止无限循环很简单。 while (choice != 1 || choice != 2 || choice != 3 || choice != 4 || choice != 5 || choice != 6 || choice != 7)是您的问题。这行的逻辑是:“如果用户输入的数字不等于1或2或3 ...继续执行循环。”但是,这意味着无论用户输入什么数字,您的循环都将继续。假设您的目标是继续向用户询问choice,直到他们另行指定为止,一个更好的循环将是:

do{
    cin >> choice;
    ...
}
while(choice != 0);

在这种情况下,如果用户输入的数字不是0-7,则程序进入cout << "\n **Invalid choice option. Please enter from numbers 1 to 7 : ",但是如果用户输入0,则程序结束。您可以将0更改为任意值。

对于将数据输入到结构中,过程非常简单。通常,您将使用重载的>>运算符,但是现在看来这超出了您当前的范围,因此我们将以更基本的方式进行操作。除非您确定要读的员工数量,否则需要使用employee类型的向量。 为了方便使用,将char的数组更改为结构中的字符串。以下代码是如何读取数据的模板。

vector<employee> parse_text(){
    ifstream fin("lines.txt");
    vector<employee> employees;
    while(!fin.eof()){
        string temp_id, temp_fname, temp_lname;
        employee temp;
        fin >> temp_fname >> temp_lname;
        temp.fullName = temp_fname + temp_lname;
        fin >> temp_id;
        temp.staffId = (int)temp_id;
        ...
        employees.push_back(temp);
        }
    fin.close();
    return employees;
}

很显然,您必须添加几行,但这足以使您入门。当前,它会读取员工的名字和姓氏,并将其连接起来,并将其存储为员工的fullName。然后,它读取员工的ID,将其强制转换为int(因为getline存储字符串),然后将其存储为staffId。冲洗并重复其余的变量,您将拥有一个员工向量。