我不知道如何在 C++ 中模拟输入停止
I don't know how to simulate input stop in C++
所以我有一个程序,它为每个学生加载成绩并输出姓名和最终成绩。它是 Accelerated C++ 书中的程序,我发现了一个问题,我不知道如何模拟停止输入。
输入示例:
Harry 98 58 78 56 98 78 58 58
,然后我按回车,会读到另一个学生,所以我写:
Jack 88 54 33 89 54 67 15 78
现在我按 Enter 并想停止阅读学生并查看输出,但我如何在程序中没有其他条件的情况下执行此操作。我读了一些关于 EOF
的文章,但是当我尝试 Ctrl+Z 时,这似乎不起作用。
代码
main.cpp
#include <algorithm>
#include <iomanip>
#include <ios>
#include <stdexcept>
#include <string>
#include <vector>
#include "grade.h"
#include "student_info.h"
using namespace std;
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;
}
grade.h
#ifndef GUARD_grade_h
#define GUARD_grade_h
#include <vector>
#include "student_info.h"
double grade(double, double, double);
double grade(double, double, const std::vector<double>&);
double grade(const Student_info &);
#endif // !GUARD_grade_h
grade.cpp
#include <vector>
#include <stdexcept>
#include "median.h"
#include "student_info.h"
#include "grade.h"
using std::domain_error; using std::vector;
double grade(double midterm, double final, double homeworks)
{
return 0.2 * midterm + 0.4 * final + 0.4 * homeworks;
}
double grade(double midterm, double final, const vector<double> &hm)
{
if (hm.size() == 0)
throw domain_error("student has done no homework");
return grade(midterm, final, median(hm));
}
double grade(const Student_info& s)
{
return grade(s.midterm, s.final, s.homework);
}
student_info.h
#ifndef GUARD_student_info_h
#define GUARD_student_info_h
#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_h
student_info.cpp
#include "student_info.h"
#include <vector>
#include <iostream>
#include <string>
using std::istream; using std::vector;
bool compare(const Student_info& x, const Student_info& y) {
return x.name < y.name;
}
istream& read_hw(istream& in, vector<double>& hm) {
if (in) {
//get rid of previous contents
hm.clear();
//read homework grades
double x;
while (in >> x)
hm.push_back(x);
//clear the stream so that input will work for the next student
in.clear();
}
return in;
}
istream& read(istream& is, Student_info& s) {
is >> s.name >> s.midterm >> s.final;
read_hw(is, s.homework);
return is;
}
median.h
#ifndef GUARD_median_h
#define GUARD_median_h
#include <vector>
double median(std::vector<double>);
#endif
median.cpp
#include "median.h"
#include <vector>
#include <algorithm>
#include <stdexcept>
using std::domain_error; using std::sort; using std::vector;
double median(vector<double> vec) {
typedef vector<double>::size_type vc_sz;
vc_sz size = vec.size();
if (size == 0)
throw domain_error("median of an empty vector");
sort(vec.begin(), vec.end());
vc_sz mid = size / 2;
return size % 2 == 0 ? (vec[mid] + vec[mid - 1]) / 2
: vec[mid];
}
要通过 EOF
你需要按 Ctrl+D.
如果这不起作用,您可能需要考虑引入 “停止字符串”。您将在每次开始新输入系列时检查一个。一般是以下形式:
if (input_string != stop_string)
/* continue further */;
else
/* stop getting input */;
所以,你可以看看下面的方法。我们让 main.cpp
中的循环保持不变,它仍然迭代由 read()
编辑的输入流 return。我们管理 read()
和 return 输入流中的读取逻辑,如果命令停止输入,则设置 eofbit
:
istream& read(istream& is, Student_info& s) {
// I added this print for clarity of tests
std::cout << "Enter name, midterm, final (or 'stop'): " << '\n';
std::string current_input;
is >> current_input;
if (current_input != "stop") { // If not `stop`, then it is a name
s.name = current_input;
is >> s.midterm >> s.final; // Get input further
} else { // We hit `stop`, set EOF, return
is.setstate(std::ios_base::eofbit);
return is;
}
read_hw(is, s.homework);
return is;
}
在 read_hw()
函数中有第二个循环,没有建议的退出:
//read homework grades
double x;
while (in >> x) { // While we have valid input...
hm.push_back(x);
}
您可以通过输入一个非数字值来停止这个。但是您也可以考虑在这里引入一个“停止字符”。像这样:
//read homework grades
double x;
while (in >> x) {
if (x == -1) // If a user inputs -1, we stop looping
break;
hm.push_back(x);
}
所以我有一个程序,它为每个学生加载成绩并输出姓名和最终成绩。它是 Accelerated C++ 书中的程序,我发现了一个问题,我不知道如何模拟停止输入。
输入示例:
Harry 98 58 78 56 98 78 58 58
,然后我按回车,会读到另一个学生,所以我写:
Jack 88 54 33 89 54 67 15 78
现在我按 Enter 并想停止阅读学生并查看输出,但我如何在程序中没有其他条件的情况下执行此操作。我读了一些关于 EOF
的文章,但是当我尝试 Ctrl+Z 时,这似乎不起作用。
代码
main.cpp
#include <algorithm>
#include <iomanip>
#include <ios>
#include <stdexcept>
#include <string>
#include <vector>
#include "grade.h"
#include "student_info.h"
using namespace std;
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;
}
grade.h
#ifndef GUARD_grade_h
#define GUARD_grade_h
#include <vector>
#include "student_info.h"
double grade(double, double, double);
double grade(double, double, const std::vector<double>&);
double grade(const Student_info &);
#endif // !GUARD_grade_h
grade.cpp
#include <vector>
#include <stdexcept>
#include "median.h"
#include "student_info.h"
#include "grade.h"
using std::domain_error; using std::vector;
double grade(double midterm, double final, double homeworks)
{
return 0.2 * midterm + 0.4 * final + 0.4 * homeworks;
}
double grade(double midterm, double final, const vector<double> &hm)
{
if (hm.size() == 0)
throw domain_error("student has done no homework");
return grade(midterm, final, median(hm));
}
double grade(const Student_info& s)
{
return grade(s.midterm, s.final, s.homework);
}
student_info.h
#ifndef GUARD_student_info_h
#define GUARD_student_info_h
#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_h
student_info.cpp
#include "student_info.h"
#include <vector>
#include <iostream>
#include <string>
using std::istream; using std::vector;
bool compare(const Student_info& x, const Student_info& y) {
return x.name < y.name;
}
istream& read_hw(istream& in, vector<double>& hm) {
if (in) {
//get rid of previous contents
hm.clear();
//read homework grades
double x;
while (in >> x)
hm.push_back(x);
//clear the stream so that input will work for the next student
in.clear();
}
return in;
}
istream& read(istream& is, Student_info& s) {
is >> s.name >> s.midterm >> s.final;
read_hw(is, s.homework);
return is;
}
median.h
#ifndef GUARD_median_h
#define GUARD_median_h
#include <vector>
double median(std::vector<double>);
#endif
median.cpp
#include "median.h"
#include <vector>
#include <algorithm>
#include <stdexcept>
using std::domain_error; using std::sort; using std::vector;
double median(vector<double> vec) {
typedef vector<double>::size_type vc_sz;
vc_sz size = vec.size();
if (size == 0)
throw domain_error("median of an empty vector");
sort(vec.begin(), vec.end());
vc_sz mid = size / 2;
return size % 2 == 0 ? (vec[mid] + vec[mid - 1]) / 2
: vec[mid];
}
要通过 EOF
你需要按 Ctrl+D.
如果这不起作用,您可能需要考虑引入 “停止字符串”。您将在每次开始新输入系列时检查一个。一般是以下形式:
if (input_string != stop_string)
/* continue further */;
else
/* stop getting input */;
所以,你可以看看下面的方法。我们让 main.cpp
中的循环保持不变,它仍然迭代由 read()
编辑的输入流 return。我们管理 read()
和 return 输入流中的读取逻辑,如果命令停止输入,则设置 eofbit
:
istream& read(istream& is, Student_info& s) {
// I added this print for clarity of tests
std::cout << "Enter name, midterm, final (or 'stop'): " << '\n';
std::string current_input;
is >> current_input;
if (current_input != "stop") { // If not `stop`, then it is a name
s.name = current_input;
is >> s.midterm >> s.final; // Get input further
} else { // We hit `stop`, set EOF, return
is.setstate(std::ios_base::eofbit);
return is;
}
read_hw(is, s.homework);
return is;
}
在 read_hw()
函数中有第二个循环,没有建议的退出:
//read homework grades
double x;
while (in >> x) { // While we have valid input...
hm.push_back(x);
}
您可以通过输入一个非数字值来停止这个。但是您也可以考虑在这里引入一个“停止字符”。像这样:
//read homework grades
double x;
while (in >> x) {
if (x == -1) // If a user inputs -1, we stop looping
break;
hm.push_back(x);
}