2016-11-02 30 views
-3

下面我有我當前正在處理的項目的當前代碼。它是爲了取得學生及其成績檔案,平均成績,然後將它們全部放回到輸出文件中。學生人數不應超過10人,所以如果學生人數超過10人,則只應閱讀前10人,然後扭轉訂單。當給予超過10名學生的文件時,我的代碼完美無缺地工作。它似乎試圖訪問不存在的內存中的一部分。我試圖讓代碼忽略空行,它應該,但這似乎並沒有解決它。我的「閱讀」功能就是我相信問題所在。代碼無法接受超出數組大小的文件?

#include <iostream> 
#include <fstream> 
#include <sstream> 
#include <iomanip> 

using namespace std; 

//My student structure that holds the variable for each student object. 
struct Student 
{ 
    string fname; 
    string lname; 
    double average; 
}; 

//Prototyping the functions to read the input file into an array and then reverse it. 
int read(ifstream &fin, Student s[]); 

void print(ofstream &fout, Student s[], int amount); 

void reverse(Student s[], int amount); 

int main() 
{ 
    //Creating the file streams and global constant for the array and the filling it with I/O. 
    const int size = 10; 
    ifstream fin; 
    ofstream fout; 
    string inputFile; 
    string outputFile; 
    Student s[size]; 

    cout << "Enter input filename: "; 
    cin >> inputFile; 
    cout << "Enter output filename: "; 
    cin >> outputFile; 

    //opeining the files given by the user and then testing if the opened. 
    fin.open(inputFile.c_str()); 
    fout.open(outputFile.c_str()); 

    if(fin.fail()) { 
     cout << "Unable to open input file.\n"; 
     return 1; 
    } 


    //calling my 3 functions and then returning to main(). Closing files as well. 
    int count = read(fin , s); 
    reverse(s, count); 
    print(fout, s, count); 
    count = 0; 

    fin.close(); 
    fout.close(); 

} 

//This function reads the file given and breaks it up using string stream. It then calculates the averages for each stuent and assigns it to the array. 
int read(ifstream &fin, Student s[]) 
{ 
    istringstream sin; 
    string line; 
    string firstName; 
    string lastName; 
    double score; 
    double total; 
    double i=0; 
    int totalStudents=0; 
    Student stu; 
    for(int j = 0; j < 10; j++){ 
    while(getline(fin, line)){ 
     sin.clear(); 

     if(line.empty()) 
     { 
      j--; 
     }else{ 
      sin.str(line); 
     while(sin >> firstName >> lastName){ 
      stu.fname = firstName; 
      stu.lname = lastName; 

      while(sin >> score){ 
      total += score; 
      i++; 
      stu.average = (total/i); 
      } 
     } 
     s[totalStudents]=stu; 
     totalStudents++; 
     stu.average = 0; 
     total = 0; 
     i = 0; 

    } 
    } 
    } 

    //returning the number of students in the file so it can later be used for the variable of total students. 
    return totalStudents; 
} 

//My print function that puts the array into a given output file. 
void print(ofstream &fout, Student s[], int amount) 
{ 
    for(int i = 0; i<amount; i++) 
    { 
     if(s[i].lname.empty()) 
     { 
      fout<<"No students to report."; 
     }else{ 
     ostringstream sout; 
     sout << s[i].lname.c_str() << ", " << s[i].fname.c_str(); 
     fout <<setw(21)<< left << sout.str() << setprecision(2) << fixed << "= " << s[i].average << '\n'; 
    } 
    } 
} 

//the function that reverses the order of the students by copying the last student into a temporary variable and casting it to the beggining. 
void reverse(Student s[], int amount) 
{ 
    Student temp; 
    for(int i=0; i< amount/2; i++) 
    { 

     temp=s[i]; 
     s[i]=s[amount-i-1]; 
     s[amount - i - 1] = temp; 
    } 
} 
+4

'爲(INT J = 0;Ĵ<10; J ++){ 而(函數getline(鰭,線)){',看起來腥 – AndyG

+2

解決這些問題的正確工具是你的調試器。在*堆棧溢出問題之前,您應該逐行執行您的代碼。如需更多幫助,請閱讀[如何調試小程序(由Eric Lippert撰寫)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)。至少,您應該\編輯您的問題,以包含一個[最小,完整和可驗證](http://stackoverflow.com/help/mcve)示例,該示例再現了您的問題,以及您在調試器。 –

回答

0

在我看來,尋找空行,你應該嘗試使用continue聲明,而不是後:

for (int j = 0; j < 10; j++) { 
    while (getline(fin, line)) { 
     sin.clear(); 

     if (line.empty()) 
     { 
      continue; 
     } 
     else { 
      sin.str(line); 
      while (sin >> firstName >> lastName) { 
       stu.fname = firstName; 
       stu.lname = lastName; 

       while (sin >> score) { 
        total += score; 
        i++; 
        stu.average = (total/i); 
       } 
      } 
      s[j] = stu; 
      stu.average = 0; 
      total = 0; 
      i = 0; 

     } 
    } 
} 

按照意見,我錯過了有關for循環。它可以完全消除,只是有while循環和計數器:

int j = 0; 
while (getline(fin, line) && j < 10) 
{ 
    sin.clear(); 

    if (line.empty()) 
    { 
     continue; 
    } 
    else 
    { 
     sin.str(line); 
     while (sin >> firstName >> lastName) 
     { 
      stu.fname = firstName; 
      stu.lname = lastName; 

      while (sin >> score) 
      { 
       total += score; 
       i++; 
       stu.average = (total/i); 
      } 
     } 
     s[j] = stu; 
     stu.average = 0; 
     total = 0; 
     i = 0; 
     j++; 
    } 
} 
+0

可能不會幫助。在閱讀某個學生後,OP仍然需要跳出內部循環。 – AndyG

+0

我想我的問題可能與totalStudents變量。數組的最大大小是10,但我認爲while循環將嘗試並超過10的值,因爲totalStudents不斷增加。我不知道如何在沒有創建無限循環的情況下改變它。 –

+0

@AndyG - 哎呀,我的壞,沒有看得太近。我添加了更好的代碼,這應該有所幫助。 – tinstaafl

相關問題