-1

テキストファイルから情報を読み取り、構造体、共用体、および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ループを使用した単純なswitchケースを作成したことです。たとえば、各段落の前の最初の文字は、学生が外国人Fであるか、シンガポール人Sであるかを示します。国籍に基づいて、情報をコピーする構造体/共用体を選択します。より良いアイデアを提供するために、これは、元のテキストファイルから情報を取り込んで処理した後の、最終的なテキスト出力ファイルの外観です。

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

以下は、問題が発生しているコードのセクションです。char変数が「S」または「F」を読み取るかどうかに関係なく、switchステートメントはそれを「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;
    }
4

1 に答える 1

0

unionC++ でa を使用した効果が見られます。

すべてのメンバーが同じメモリ ブロックを共有するという共用体の主な特徴。また、メンバー構造LocalForeignerレイアウトがまったく同じであるため、どちらを使用しても共用体の内容を出力できます。

構造の 1 つを変更すると (たとえば、nationalityから削除Local)、一部の印刷物が文字化けすることがわかります (特に、外国人学生をローカル学生として印刷するエントリ、またはその逆のエントリ)。これは、学生に使用されるメモリ ブロックが、地元の学生と外国の学生で異なる方法で解釈されるためです。
注: 技術的には、これにより未定義の動作が発生しますが、この場合、結果が壊滅的なものになる可能性は低いです。正式には、最後に書き込みを行った共用体の同じメンバー、または (メンバーが構造体の場合) 共用体に最後に書き込んだ構造体と同じ構造体の最初のメンバーのみを読み取ることができます。

于 2013-01-06T10:28:40.047 に答える