Switchcase语句问题.从文本文件中读取信息

Switchcase statement issue. Reading info from txt file c++

本文关键字:读取 信息 文件 文本 语句 问题 Switchcase      更新时间:2023-10-16

我正试图编写一个程序,从文本文件读取信息,并将其复制到使用结构体和联合和cstring的数组中。我的文本文件看起来像这样。

F South Korea
Male Psy Park Jae Sang
31 - 12 - 1977
3 CSCI114 55 CSCI103 44 GangNam 100
S Female Super Junior
5 - 8 - 1978 
2 CSCI114 60 CSCI103 80
F People Republic Of China
Unknown James Bond
11 - 12 - 1976
4 CSCI114 54 CSCI124 66 CSCI007 99 CSCI123 28

我的查询是,我写了一个简单的开关用例,其中有一个for循环,根据其标准读取信息。例如,每个段落前的第一个字母表示学生是外国人F还是新加坡人s。根据他们的国籍,我选择将他们的信息复制到哪个结构/union中。为了让您更好地理解,下面是我从原始文本文件中获取信息并对其进行处理后的最终文本输出文件。

https://i.stack.imgur.com/Bv2YS.jpg

下面是我遇到麻烦的代码部分。似乎无论字符变量是否读取"S"或"F",我的开关语句只是将其读取为"F"。

        //file to array.

        char dateJunk;
        int numOfCourses;
        int k = 0;
        while (!afile.eof())
        {
            for (int k = 0; k < 3; k++)
            {
            afile >> locale;
                switch (locale)
                {
                    case 'F':
                        afile.getline(x[k].st.foreignStudent.nationality, MAX);
                        afile >> x[k].st.foreignStudent.gender;
                        afile.getline(x[k].st.foreignStudent.name, MAX);
                        afile >> x[k].st.foreignStudent.bd.day;
                        afile >> dateJunk;
                        afile >> x[k].st.foreignStudent.bd.month;
                        afile >> dateJunk;
                        afile >> x[k].st.foreignStudent.bd.year;
                        afile >> x[k].st.foreignStudent.numOfCourses;
                        for (int i = 0; i < x[k].st.foreignStudent.numOfCourses; i++)
                        {
                            afile >> x[i].st.foreignStudent.subjects[k];
                            afile >> x[i].st.foreignStudent.grades[k];
                        }
                        break;
                    case 'S':
                        afile >> x[k].st.localStudent.gender;
                        afile.getline(x[k].st.localStudent.name, MAX);
                        afile >> x[k].st.localStudent.bd.day;
                        afile >> dateJunk;
                        afile >> x[k].st.localStudent.bd.month;
                        afile >> dateJunk;
                        afile >> x[k].st.localStudent.bd.year;
                        afile >> x[k].st.localStudent.numOfCourses;;
                        for (int i = 0; i < x[k].st.localStudent.numOfCourses; i++)
                        {
                            afile >> x[i].st.localStudent.subjects[k];
                            afile >> x[i].st.localStudent.grades[k];
                        }
                }
                }
        }
        //Tests my cstring arrays to see everything is copied in correctly.
        for (int k = 0; k < 3; k++)
        {
        cout << locale << " " << x[k].st.foreignStudent.nationality;
        cout << endl;
        cout << x[k].st.foreignStudent.gender;
        cout << x[k].st.foreignStudent.name;
        cout << endl;
        cout << x[k].st.foreignStudent.bd.day << " - ";
        cout << x[k].st.foreignStudent.bd.month << " - ";
        cout << x[k].st.foreignStudent.bd.year;
        cout << endl;
        cout << x[k].st.foreignStudent.numOfCourses;
        cout << endl;
        for(int i = 0; i < x[k].st.foreignStudent.numOfCourses; i++)
        {
        cout << x[i].st.foreignStudent.subjects[k] << " ";
        cout << x[i].st.foreignStudent.grades[k] << " ";
        }
            cout << endl;
        }
        return 0;
    }

以下是完整的代码:

    #include <iostream>
    #include <fstream>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    const int MAX = 80;
    struct Birthday
    {
        char day[MAX];
        char month[MAX];
        char year[MAX];
    };
    struct Local
    {
        char name[MAX];
        char nationality[MAX];
        char gender[MAX];
        Birthday bd;
        char subjects [MAX][MAX];
        char grades [MAX][MAX];
        int numOfCourses;
    };
    struct Foreigner
    {
        char name[MAX];
        char nationality[MAX];
        char gender[MAX];
        Birthday bd;
        char subjects [MAX][MAX];
        char grades [MAX][MAX];
        int numOfCourses;
    };
    union Student
    {
        Local     localStudent;
        Foreigner foreignStudent;
    };
    enum CountryType {S, F};
    struct UowStudents
    {
        CountryType ct;
        Student st;
    };
    int fileToArray (fstream& afile, char fileName [], UowStudents* x, char& locale);
    int main ()
    {
        srand(time_t(NULL));
        fstream afile;
        UowStudents x [MAX];
        char fileName[MAX];
        char locale;
        cout << "Enter filename: ";
        cin >> fileName;
        int size = fileToArray (afile, fileName, x, locale);

    }
    int fileToArray (fstream& afile, char fileName [], UowStudents* x, char& locale)
    {
        afile.open(fileName, ios::in);
        if (!afile)
        {
            cout << fileName << "could not be opened for read" << endl;
            exit (-1);
        }
        //file to array.

        char dateJunk;
        int numOfCourses;
        int k = 0;
        while (!afile.eof())
        {
            for (int k = 0; k < 3; k++)
            {
            afile >> locale;
                switch (locale)
                {
                    case 'F':
                        afile.getline(x[k].st.foreignStudent.nationality, MAX);
                        afile >> x[k].st.foreignStudent.gender;
                        afile.getline(x[k].st.foreignStudent.name, MAX);
                        afile >> x[k].st.foreignStudent.bd.day;
                        afile >> dateJunk;
                        afile >> x[k].st.foreignStudent.bd.month;
                        afile >> dateJunk;
                        afile >> x[k].st.foreignStudent.bd.year;
                        afile >> x[k].st.foreignStudent.numOfCourses;
                        for (int i = 0; i < x[k].st.foreignStudent.numOfCourses; i++)
                        {
                            afile >> x[i].st.foreignStudent.subjects[k];
                            afile >> x[i].st.foreignStudent.grades[k];
                        }
                        break;
                    case 'S':
                        afile >> x[k].st.localStudent.gender;
                        afile.getline(x[k].st.localStudent.name, MAX);
                        afile >> x[k].st.localStudent.bd.day;
                        afile >> dateJunk;
                        afile >> x[k].st.localStudent.bd.month;
                        afile >> dateJunk;
                        afile >> x[k].st.localStudent.bd.year;
                        afile >> x[k].st.localStudent.numOfCourses;;
                        for (int i = 0; i < x[k].st.localStudent.numOfCourses; i++)
                        {
                            afile >> x[i].st.localStudent.subjects[k];
                            afile >> x[i].st.localStudent.grades[k];
                        }
                }
                }
        }
        //Tests my cstring arrays to see everything is copied in correctly.
        //The print for foreign student cstrings also has information for the
        //one Singaporean student "S" in the middle. Singaporean must go into
        //the local cstrings.
        for (int k = 0; k < 3; k++)
        {
        cout << locale << " " << x[k].st.foreignStudent.nationality;
        cout << endl;
        cout << x[k].st.foreignStudent.gender;
        cout << x[k].st.foreignStudent.name;
        cout << endl;
        cout << x[k].st.foreignStudent.bd.day << " - ";
        cout << x[k].st.foreignStudent.bd.month << " - ";
        cout << x[k].st.foreignStudent.bd.year;
        cout << endl;
        cout << x[k].st.foreignStudent.numOfCourses;
        cout << endl;
        for(int i = 0; i < x[k].st.foreignStudent.numOfCourses; i++)
        {
        cout << x[i].st.foreignStudent.subjects[k] << " ";
        cout << x[i].st.foreignStudent.grades[k] << " ";
        }
            cout << endl;
        }
//as you can see, everything gets copied into localStudent struct as well.
        for (int k = 0; k < 3; k++)
        {
            cout << x[k].st.localStudent.gender;
            cout << x[k].st.localStudent.name;
            cout << endl;
            cout << x[k].st.localStudent.bd.day << " - ";
            cout << x[k].st.localStudent.bd.month << " - ";
            cout << x[k].st.localStudent.bd.year;
            cout << endl;
            cout << x[k].st.localStudent.numOfCourses;
            cout << endl;
            for(int i = 0; i < x[k].st.localStudent.numOfCourses; i++)
            {
                cout << x[i].st.localStudent.subjects[k] << " ";
                cout << x[i].st.localStudent.grades[k] << " ";
            }
            cout << endl;
        }


        return 0;
    }

您可以看到在c++中使用union的效果。

union的主要特征是所有成员共享同一块内存。因为你的成员结构LocalForeigner有完全相同的布局,你可以使用任何一个来打印联合的内容。

如果您更改其中一个结构(例如,从Local中删除nationality),您将看到一些打印输出被乱码(特别是,那些您将外国学生打印为本地学生的条目,反之亦然)。这是因为本地学生和外国学生使用的内存块的解释不同。
注意:从技术上讲,这会导致未定义的行为,但在这种情况下,结果不太可能是灾难性的。正式地说,您只能读取上次写入的联合的相同成员,或者(如果成员是结构体)与上次写入联合的结构体中相同的结构体的初始成员。