私はAccelerated 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
すべての読書に 'std :: istream :: operator >>'を使っています。 'operator >>'は改行を無視し、空白に遭遇したときに文字列の読み込みを停止します。また、試験や宿題を含まない数行では、読解は失敗します。あなたはいつもあなたが期待していることを読んでいるわけではありません。最初に 'std :: getline()'を使ってテキストの行全体を 'std :: string'に読み込み、' std :: istreamstream'を使って必要に応じてその行から個々の値を読み込むことを検討してください。 –
プログラムの動作を理解するために必要なファイルであるstudent_info.hを含むように編集されました。完全な情報源はここにあります:https://github.com/acarabott/accelerated-cplusplus/tree/master/04 – Squirrel
[mcve]のみを含むように質問を編集することを検討してください...実際には2つの機能しかないようですistreamから読んでいるので、読まなければならないコードの数を明らかに減らすことができます。 – zett42