[英]How do I read an array of structs from a file and sort it?
前言:教授設定的准則,我必須使用數組,而不是其他一些數據結構。 我們應該遵循的方法的偽代碼(不是很簡潔):
name and grade are read into a temporary location
loop from the end of the filled part of the array down to beginning {
if (new last name < current last name) {
copy current name and grade down
}
else if (new/current last names are equal and new first name < current first name) {
copy/assign current name and grade down
}
else {
found right place, break out of loop
}
}
now that you've made room, insert (copy) new name into correct sorted position
我看到我可能試圖讀取數組位置[-1]來打破數組界限,但是我想不出一種避免這種情況的方法,因為我是從已有的項目數中倒數,並且必須比較它們。
我正在從文本文件中讀取行,並將每一行的片段存儲到結構中。 然后,我使用一種插入排序式算法來按字母順序存儲結構。 但是,我的數組似乎並沒有用新行來填充前幾行,而只是覆蓋了前幾行……這似乎是我的一個比較測試失敗了,因為我的復制位置似乎從未改變,盡管這可能是因為初始數組填充在某種程度上失敗了。 我覺得很愚蠢,我必須缺少一些簡單的東西...而且,我的DisplayList模塊顯然也永遠不會獲得填充了任何東西的數組。 我是否以錯誤的方式更改了陣列?
這是有問題的模塊:
bool sortInput(ifstream &infile, StudentType students[], int size)
{
StudentType temp;
int copyToHere;
if(size == 0)
{
infile >> temp.last >> temp.first >> temp.grade;
strcpy(students[0].last, temp.last);
strcpy(students[0].first, temp.first);
students[0].grade = temp.grade;
size++;
}
while(infile)
{
infile >> temp.last >> temp.first >> temp.grade;
//cout << "TEST" << temp.last << temp.first << temp.grade << endl;
for(int i = size; i > 0; i--)
{
if(strcmp(temp.last, students[i-1].last) < 0)
{
students[i] = students[i-1];
students[i-1] = temp;
}
else if(strcmp(temp.last, students[i].last) == 0 && strcmp(temp.first, students[i].first) < 0)
{
students[i] = students[i-1];
}
else
{
break;
}
copyToHere = i;
}
cout << "Size = " << size << " and copy position = " << copyToHere << endl;
students[copyToHere] = temp;
size++;
//test to see if array is populated properly
for(int i = 0; i < size; i++)
{
cout << "Name is " << students[i].first << " " << students[i].last << " and grade is " << students[i].grade << endl;
}
cout << "DONE" << endl;
} //end while loop
return true;
}
這是完整的代碼(如有必要,無論出於何種原因或其他情況):
// ----------------------------------------------------------------------------
// You write meaningful doxygen comments and assumptions
#include <string.h>
#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;
int const MAXSIZE = 100; // maximum number of records in total
int const MAXLENGTH = 31; // maximum string length
int const MAXGRADE = 100; // highest possible grade
int const LOWGRADE = 0; // lowest possible grade
int const GROUP = 10; // group amount
int const HISTOGRAMSIZE = (MAXGRADE-LOWGRADE)/GROUP + 1; // grouped by GROUP
struct StudentType { // information of one student
int grade; // the grade of the student
char last[MAXLENGTH]; // last name (MAXLENGTH-1 at most)
char first[MAXLENGTH]; // first name (MAXLENGTH-1 at most)
};
// prototypes go here
bool sortInput(ifstream &, StudentType [], int);
void displayList(StudentType [], int);
/*setHistrogram();
displayHistogram();
findAverage();*/
//------------------------------- main ----------------------------------------
int main() {
StudentType students[MAXSIZE]; // list of MAXSIZE number of students
int size = 0; // total number of students
int histogram[HISTOGRAMSIZE]; // grades grouped by GROUP
int average = 0; // average exam score, truncated
// creates file object and opens the data file
ifstream infile("data1.txt");
if (!infile) {
cout << "File could not be opened." << endl;
return 1;
}
// read and sort input by last then first name
bool successfulRead = sortInput(infile, students, size);
// display list, histogram, and class average
if (successfulRead) {
displayList(students, size);
// setHistogram(... you figure parameters ...);
// displayHistogram(... you figure parameters ...);
// average = findAverage(... you figure parameters ...);
cout << "Average grade: " << average << endl << endl;
}
return 0;
}
bool sortInput(ifstream &infile, StudentType students[], int size)
{
StudentType temp;
int copyToHere;
if(size == 0)
{
infile >> temp.last >> temp.first >> temp.grade;
strcpy(students[0].last, temp.last);
strcpy(students[0].first, temp.first);
students[0].grade = temp.grade;
size++;
}
while(infile)
{
infile >> temp.last >> temp.first >> temp.grade;
//cout << "TEST" << temp.last << temp.first << temp.grade << endl;
for(int i = size; i > 0; i--)
{
if(strcmp(temp.last, students[i-1].last) < 0)
{
students[i] = students[i-1];
students[i-1] = temp;
}
else if(strcmp(temp.last, students[i].last) == 0 && strcmp(temp.first, students[i].first) < 0)
{
students[i] = students[i-1];
}
else
{
break;
}
copyToHere = i;
}
cout << "Size = " << size << " and copy position = " << copyToHere << endl;
students[copyToHere] = temp;
size++;
//test to see if array is populated properly
for(int i = 0; i < size; i++)
{
cout << "Name is " << students[i].first << " " << students[i].last << " and grade is " << students[i].grade << endl;
}
cout << "DONE" << endl;
} //end while loop
return true;
}
void displayList(StudentType students[], int size)
{
cout << "List of names sorted:" << endl;
for(int i = 0; i < size; i++)
{
cout << " " << students[i].grade << " " << students[i].last << " " << students[i].first << endl;
}
}
// ----------------------------------------------------------------------------
// functions with meaningful doxygen comments and assumptions go here
您的插入排序實際上沒有正確插入。 讓我們看一下主插入循環的一部分:
if(strcmp(temp.last, students[i-1].last) < 0)
{
students[i] = students[i-1];
students[i-1] = temp;
}
這樣做的目的顯然是將temp
插入位置i-1
處的數組中。 您正在將i-1
處的項移動到i
但是數組中其他元素發生了什么? 您需要將它們全部上移一個位置,以便為插入的元素騰出空間。 就像是:
memmove(students + i, students + i - 1, sizeof(students[0]) * size - i - 1);
您的代碼中也有其他問題。 copyToHere
可能未初始化。 您要多次將temp
復制到數組中( students[i-1] = temp;
和students[copyToHere] = temp;
都不需要)。 一旦完成內循環的插入,就應該開始操作。 當列表為空時,您不需要進行特殊處理,依此類推。
解決我自己的問題哈哈。 我因沒有正確完成else語句而感到愚蠢。 現在,我正在嘗試重做我的名字比較,因為出現問題是因為它不會按字母順序排列相同的姓氏。
經驗教訓:在認為您被分叉之前,請認真研究所有內容。 現在我真的感覺自己像個白痴,希望不會浪費很多窺視時間。
for(int i = size; i > 0; i--)
{
if(strcmp(temp.last, students[i-1].last) < 0)
{
students[i] = students[i-1];
students[i-1] = temp;
}
else if(strcmp(temp.last, students[i].last) == 0 && strcmp(temp.first, students[i].first) < 0)
{
students[i] = students[i-1];
students[i-1] = temp;
}
else
{
students[i] = temp;
break;
}
insertHere = i;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.