将文件读入 C++ 结构体数组

4
我将尝试在此程序中将一个 .txt 文件读入到一个结构体数组中,并显示其内容。
该文件的格式如下:
Smith   Jack    60    45    98  
Harry   Hisk    45    40    78  
Kay     Jacob   35.5  23    45  
Dos      hed    23    20    35  
Noa      Tom    55    12    32  
Joe      Peni   57    49    78  
Vin      San    25.6  23    65.5  
Jes      Dan    24.3  12    78  
Zi       Lee    56    49    99  
Angi     Dev    57    48    97  
Donald   David  60    50    96  
Davis    Lal    47    47    80  
Alvis   Sen     56    46    85  
Jack    Jill    45    45    75  
Messy   Lionel  60    49    100  

我正在运行的代码:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main(){
    const int SIZE=50;
    int i;
    struct Records {
        string firstname;
        string secondname;
        float test1mark;
        float midtestmark;
        float annualmark;
    }record[SIZE];

    ifstream in("Data.txt");

    if (!in){
    cerr << "File can't be opened! " << endl;
    system("PAUSE");
    exit(1);
    }
    for (int i=0; i < SIZE; i++){
    in >> record[i].firstname >> record[i].secondname 
    >>record[i].test1mark >> record[i].midtestmark >> record[i].annualmark ;
    }
    for (int i=0;i< SIZE;i++) {
        cout << record[i].firstname<<"  ";
        cout << record[i].secondname<<" ";
        cout << record[i].test1mark<<"  ";
        cout << record[i].midtestmark << "  ";
        cout << record[i].annualmark << "   ";
    }   
return 0;
} 

我所得到的输出:
Smith   Jack    60      45      98  
Harry   Hisk    45      40      78  
Kay     Jacob   35.5    23      45  
Dos     hed     23      20      35    
Noa     Tom     55      12      32  
Joe     Peni    57      49      78  
Vin     San     25.6    23      65.5  
Jes     Dan     24.3    12      78  
Zi      Lee     56      49      99  
Angi    Dev     57      48      97  
Donald  David   60      50      96  
Davis   Lal     47      47      80  
Alvis   Sen     56      46      85  
Jack    Jill    45      45      75  
Messy   Lionel  60      49      100  
                nan     0       8.94237e-039  
                4.36192e-039    0       -2.3511e-038  
                0       0       -2.3511e-038  
                0       0       0  
                1.32253e-038    0       1.32251e-038  
                4.2039e-045     0       -2.11122e+037  
                1.32251e-038    0       3.21276e-039  
                1.4013e-045     0       -2.3511e-038  
                1.4013e-045     0       3.76158e-037  
                0       0       3.76158e-037  
                0       0       1.12104e-044  
                4.36195e-039    0       4.36194e-039  
                3.57331e-043    0       6.0615e-039  
                0       0       3.21276e-039  
                4.2039e-045     0       6.41272e-039  
                1.12104e-044    0       6.63812e-039  
                4.36205e-039    0       -2.75237e+038  
                0       0       6.59812e-039  
                6.63426e-039    0       1.4013e-045  
                0       0       6.47961e-039  
                3.21319e-039    0       3.21319e-039  
                6.59812e-039    0       3.21299e-039  
                8.40779e-045    2.24208e-044    6.01433e-039  
                6.6045e-039     0       2.54408e-029  
                0       0       6.6045e-039  
                0       0       6.43946e-039  
                5.88656e-039    0       -4.12495e+011  
                0       0       0
                5.88656e-039    0       2.54408e-029  
                nan     nan     6.43029e-039  
                0       0       0
                5.93823e-039    0       -4.12495e+011  
                0       0       0
                5.93823e-039    0       5.74532e-044  
                nan     nan     5.93837e-039  

进程在0.05447秒后以返回值0退出
按任意键继续. . .

有人能告诉我它的问题在哪里吗?我尝试使用指针,但情况变得更糟了。 -初学者


for (int i=0; i < SIZE; i++){ -- 你怎么知道要读取50个数据项? - PaulMcKenzie
@PaulMcKenzie 这是一个作业问题,而且这是要求之一。 - Avisaki Usamate
1
我不在你的班级里,所以我只能给出一般性的回答。如果你数一下,你并没有50个项目,因此在第15个项目之后,你的循环读取了垃圾数据。无论如何,你都不应该像这样编写“读取循环”。你应该循环直到文件结束,或者直到达到预设的限制,以先到者为准。对于你来说,文件结束先到了,但你仍然继续循环。 - PaulMcKenzie
谢谢@PaulMcKenzie - Avisaki Usamate
3个回答

4
您的文件有 15 行,因此您只能读取 15 行数据。您正在使用变量 SIZE 来控制应读取多少行。
问题在于 SIZE50!它 不是 15。当您尝试读取超出文件末尾时,输入将不会超过第 16 行。因此,索引为 15 之后的变量将未初始化,这是未定义的
要么增加文件中的行数到 50,要么将 SIZE 更改为 15

谢谢你!这就是我要做的所有事情 :) - Avisaki Usamate
从已设置EOF的流中提取数据并不会导致未定义行为,只是没有输入发生。将未初始化的数据插入到cout中会导致未定义行为。 - David Thomas
@DavidThomas 完全正确 :) 谢谢 - Rakete1111

3

正如 @Rackete1111 的另一个答案所述,您指定了太多的项目,并且使读取数据的循环超过文件中实际项目数。

话虽如此,如果您正确编写读取循环,实际上没有任何问题(除了预先设置数组过大浪费空间),即使您错误地声明了50个项目而不是15个项目,也是可以的。以下是编写循环的方法:

#include <iostream>
#include <string>
#include <iostream>

using namespace std;

int main(){
    const int SIZE=50;
    int i;
    struct Records {
        string firstname;
        string secondname;
        float test1mark;
        float midtestmark;
        float annualmark;
    };

    Records record[SIZE];

    ifstream in("Data.txt");

    int recCount = 0;  // keep track of actual number of records

    // loop until we reach the end of file, or until we hit SIZE records,
    // whichever comes first
    while (recCount < SIZE && 
          (in >> record[recCount].firstname >> 
                 record[recCount].secondname >>
                 record[recCount].test1mark >> 
                 record[recCount].midtestmark >> 
                 record[recCount].annualmark))
    {
        ++recCount;
    }
    
    // now recCount == 15 if you have 15 items.

演示实例

请注意我们有一个while循环,它将一直读取直到达到限制(50)或者到达文件末尾。


但是 [while(!eof...) 被认为是错误的] (https://dev59.com/NW035IYBdhLWcg3wJcYv) @PaulMcKenzie - Avisaki Usamate

-1

我相信我们不需要那个

int i;

一开始

#include <iostream>
#include <string>
#include <fstream>
using namespace std;



ifstream in("Data.txt");
const int SIZE = 15;
void debugPrint();
void loadData();

struct Records {
    string firstname;
    string secondname;
    float test1mark;
    float midtestmark;
    float annualmark;   
}record[SIZE];

int main()
    {
    loadData();
    debugPrint();
    }

void debugPrint()
{
    for (int i = 0; i < SIZE; i++) 
    {
        cout << record[i].firstname << "  ";
        cout << record[i].secondname << " ";
        cout << record[i].test1mark << "  ";
        cout << record[i].midtestmark << "  ";
        cout << record[i].annualmark << "  " <<endl;        
    }
    system("PAUSE");
}

void loadData()
{   
    for (int i = 0; i < SIZE; i++)
    {
        if (!in)
        {                                               
            cerr << "File can't be opened! " << endl;
            system("PAUSE");
        }

        in >> record[i].firstname >> record[i].secondname
        >> record[i].test1mark >> record[i].midtestmark >> record[i].annualmark;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接