2017-02-27 67 views
-1

我正在通过本书中的练习加速C++,并且在阅读while循环中的字符串时遇到问题。该代码似乎有点选择该人的名字读取多少。任何想法为什么这被切断?我已经进入Xcode进行调试,看起来全名只是没有被读入。cin没有阅读完整字符串

代码的想法是,你可以键入一个学生的名字,然后是期中考试,期末考试然后一系列作业成绩来计算他们的最终成绩。然后它会按字母顺序返回名称,并在其旁边显示最终标记,并将其格式化,以便最终标记位于单个列中。

GradeFinder.ccp(主)

#include <algorithm> 
#include <iomanip> 
#include <ios> 
#include <iostream> 
#include <stdexcept> 
#include <string> 
#include <vector> 
#include "grade.cpp" 


using std::cin; 
using std::cout; 
using std::endl; 
using std::domain_error; 
using std::max; 
using std::setprecision; 
using std::sort; 
using std::streamsize; 
using std::string; 
using std::vector; 

int main() 
{ 
    vector<Student_info> students; 
    Student_info record; 
    string::size_type maxlen=0; 

    while (read(cin,record)) 
    { 
    maxlen=max(maxlen,record.name.size()); 
    students.push_back(record); 
    } 

    sort(students.begin(),students.end(),compare); 

    for (vector<Student_info>::size_type i=0; i!=students.size();++i) 
    { 
    cout<<students[i].name 
     <<string(maxlen+1-students[i].name.size(),' '); 

     try 
     { 
     double final_grade=grade(students[i]); 
     streamsize prec=cout.precision(); 
     cout<<setprecision(3)<<final_grade 
      <<setprecision(prec); 
      } 
     catch (domain_error e) 
     { 
      cout<<e.what(); 
     } 
     cout<<endl; 
    } 
return 0; 
} 

'Student_info.h'

#ifndef GUARD_Student_info 
#define GUARD_Student_info 

// Student_info.h header file 
#include <iostream> 
#include <string> 
#include <vector> 

struct Student_info { 
    std::string name; 
    double midterm, final; 
    std::vector<double> homework; 
}; 

bool compare(const Student_info&, const Student_info&); 
std::istream& read(std::istream&, Student_info&); 
std::istream& read_hw(std::istream&, std::vector<double>&); 

#endif // GUARD_Student_info 

Student_info.cpp(读取的名称和相关的标记的命令行输入)

#include "Student_info.h" 

using std::istream; 
using std::vector; 

bool compare(const Student_info& x, const Student_info& y) 
{ 
    return x.name<y.name; 
} 

istream& read(istream& is, Student_info& s) 
{ 
    is >> s.name >> s.midterm >> s.exam; 
    read_hw(is,s.homework); 
    return is; 
} 

istream& read_hw(istream& in, vector<double>& hw) 
{ 
    if (in) 
    { 
     hw.clear(); 

     double x; 
     while (in>>x) 
     hw.push_back(x);  
    in.clear(); 

    } 
    return in; 
}  

的以下是命令行输入的一个例子,有趣的是这个名字当佩内洛普不是输入的第一个名字时,会导致问题,而约翰尼总是很好。

Chapter4 Alex$ ./GradeFinder 
Johnny 90 90 90 90 90 
Frederick 80 80 80 80 80 
Penelope 85 85 85 85 85 
Polly 95 95 95 95 95 95 
Johnny 90 
lope  85 
olly  95 
rederick 80 

Chapter4 Alex$ ./GradeFinder 
Penelope 85 85 85 85 85 
Frederick 80 80 80 80 80 80 
Polly 95 95 95 95 95 95 
Johnny 90 90 90 90 90 90 
Johnny 90 
Penelope 85 
olly  95 
rederick 80 
+2

您正在使用'std :: istream :: operator >>'进行所有阅读。 'operator >>'忽略换行符,并在遇到空格时停止读取字符串。此外,在少数不包含任何考试或家庭作业分数的线上,您的阅读将会失败。所以你并不总是阅读你所期望的。考虑首先使用'std :: getline()'将整行文本读入'std :: string',然后根据需要使用'std :: istreamstream'从该行读取单个值。 –

+0

编辑包含student_info.h,这是理解程序行为的必要文件。完整的源代码在这里:https://github.com/acarabott/accelerated-cplusplus/tree/master/04 – Squirrel

+0

请考虑编辑你的问题只包含[mcve] ...它似乎只有2个函数实际上从istream中读取,所以你可以明显减少我们必须读取的代码数量。 – zett42

回答

0

看来问题是,使用libc++似乎吞某些字符(A,B,C,d,E,F,I,N,P,X),当他们出现在名称的开始。

通过切换编译为libstdc++它不再删除名称中的字符。但是,我不知道如何解决这个问题,同时仍然使用libc++

请参阅here以获取相同问题的答案。它似乎可能是一个Mac相关的问题。