2011-11-28 86 views
0

我無法準確指出我的文件輸入出錯了。下面是代碼:ifstream不規則模式

char tempFirst[20], tempLast[20], tempCourse[7]; 
    char c;   // For peeking 


    // Find out how many students are in the file 
    inFile >> numStudents; 

    for (int i = 0; i < numStudents; i++) 
    { 
     // Get last name from file 
     inFile.getline(tempLast, 20, ','); 

     // Gets rid of any spaces inbetween last and first 
     while (isspace(inFile.peek())) 
     c = inFile.get(); 
     // Get first name from file 
     inFile.getline(tempFirst, 20, '\n'); 

     // New line, get course 
     inFile >> tempCourse; 

     // PRINT 
     cout << tempFirst << "\n" << tempLast << "\n" 
      << tempCourse << "\n"; 

     list[i]->SetGrades(inFile); 
    } 

SetGrade導致了這三種繼承功能之一:

void EnglishStudent::SetGrades(ifstream& inFile) 
{ 
    inFile >> attendance >> project >> midterm >> final; 
    cout << attendance << " " << project << " " << midterm << " " << final << "\n\n"; 
} 

void HistoryStudent::SetGrades(ifstream& inFile) 
{ 
    inFile >> paper >> midterm >> final; 
    cout << paper << " " << midterm << " " << final << "\n\n"; 
} 

void MathStudent::SetGrades(ifstream& inFile) 
{ 
    inFile >> quiz1 >> quiz2 >> quiz3 >> quiz4 >> quiz5 
     >> test1 >> test2 >> final; 
    cout << quiz1 << " "<< quiz2 << " " << quiz3 << " " << quiz4 << " " << quiz5 
     << " " << test1 << " " << test2 << " " << final << "\n\n"; 
} 

這裏是我從加載的信息的文件:

6 
Bunny, Bugs 
Math 90 86 80 95 100 99 96 93 
Schmuckatelli, Joe 
History 88 75 90 
Dipwart, Marvin 
English 95 76 72 88 
Crack Corn, Jimmy 
Math 44 58 23 76 50 59 77 68 
Kirk, James T. 
English 40 100 68 88 
Lewinsky, Monica 
History 60 72 78 

然後在這裏是輸出:

Bugs 

Bunny 
Math 
90 86 80 95 100 99 96 93 

Joe 

History 
88 75 90 

Marvin 

English 
95 76 72 88 

Jimmy 

Crack Corn 
Math 
44 58 23 76 50 59 77 68 

James T. 

English 
40 100 68 88 

Monica 

History 
60 72 78 

我錯過了大多數姓氏,對於第一個學生,名字包含了一個結尾。我將如何去解決這個問題?

+0

如何創建'list'並設置'名單[I]'?特別是,當我用'list'的適當定義和操作填寫了[示例代碼](http://sscce.org/)時,它打印了最後的名字。 – outis

+0

將'SetGrades'方法的參數設置爲'istream'會更好,所以它們會更通用。這將允許他們使用'cin'和'istringstream's。 – outis

+1

是否允許使用'std :: string'? (因爲我喜歡[這個'getline()'](http://www.cplusplus.com/reference/string/getline/)多於'istream :: getline()') – moooeeeep

回答

1

這不是說名字的末尾有換行符,而是換句話說,姓在開始處有一個換行符。當從輸入中讀取int時,遇到的任何標記int末尾的空白都會留在輸入流中。

要解決此問題,請在讀取姓氏之前,在SetGrades方法或循環結束時刪除空格。在閱讀numStudents之後,後兩者也需要刪除空格。刪除空格最簡單的方法是使用ws stream manipulator。它所需要的是:

inFile >> ws; 

您也可以取代你peek ING環路與此有關。

用字符串替換字符數組以獲得更真正的C++體驗。這也需要用getline免費功能替換ifstream::getline。作爲獎勵,您的代碼適用於超過19個字符的名稱。

std::string tempFirst, tempLast, tempCourse; 

    ... 
    for (int i=0; i < numStudents; ++i) { 
     inFile >> std::ws; 
     getline(inFile, last, ','); 

     inFile >> std::ws; 
     getline(inFile, first, '\n'); 
     ... 
+0

擺脫之前的空白姓氏刪除了換行符,但程序仍然沒有得到所有的姓氏。我將系統切換到字符串,它的工作原理! getline比inFile.getline好得多。謝謝! – jordaninternets

1

跳過當前行的其餘部分,然後再移動到下一行

inFile >> numStudents; 
    std::string line; 
    std::getline(inFile, line);//read the rest of the first line, you should do this before you start to read next line 
    for (int i = 0; i < numStudents; i++) 
    { 
     std::getline(inFile, line); //line contains first name and last name 
     size_t pos = line.find(","); 
     std::cout << line.substr(0, pos) << std::endl //first name 
      << line.substr(pos + 2) << std::endl; //last name,skip ", " 
     std::getline(inFile, line); // course name and grades 
     //you could split the course name and grades now with line 
     std::cout << line << std::endl; 
    } 
+0

使用std :: getline代替std :: istream :: get,std :: istream :: peek。 get和peek很難使用。他們讓你的代碼變得很難看。 – BruceAdi