2011-11-28 45 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