我正在使用Andrew Koenig和Barbara Moo(2000)编写的Accelerated C++进行工作,并停留在第4章的代码中。我认为这段代码读取了一个包含多个学生的考试,期末考试和家庭作业成绩的外部数据文件,并为每个学生返回类(class)成绩学生。
我已经从GitHub的Andrew Koenig下载了练习的解决方案:
https://github.com/bitsai/book-exercises/tree/master/Accelerated%20C%2B%2B
我可以在第4章中运行第一个示例(main1.cc
),当通过键盘输入期中,期末和作业成绩时,该示例将为单个学生返回类(class)成绩。这是一个例子:
data: harriet 85 95 88 87 93 45 76 99
student name = harriet
midterm grade = 85
final grade = 95
median of six homework grades (88, 87, 93, 45, 76, 99) = 87.5
final grade = 90
0.2 * 85 + 0.4 * 95 + 0.4 * 87.5 = 90
但是我无法运行第二个示例(main2.cc
),其中从一个外部文件读取多个学生的数据。当我创建或运行main2.exe
文件时,没有错误消息出现。当我尝试运行main2.exe
时,Windows 10命令窗口中的光标仅移至下一行,并且不显示任何内容,甚至不显示目录。这是我制作可执行文件时返回的行:c:\Users\mark_\myCppprograms\mychapter04>make
g++ main1.cc -o main1
g++ main2.cc -o main2
g++ -c -o main3.o main3.cc
g++ -c -o grade.o grade.cc
g++ -c -o median.o median.cc
g++ -c -o Student_info.o Student_info.cc
g++ main3.o grade.o median.o Student_info.o -o main3
main2.cc
中的代码很长。第4章的第三个示例(main3.cc
)将此代码分为多个C++
和header
文件,但我也无法使main3.exe
文件返回任何内容。这是
main2.cc
的代码。我将#include "../minmax.h"
更改为#include "minmax.h"
,并将文件"minmax.h"
放置在与main2.cc
相同的文件夹中。文件"minmax.h"
并非来自上述GitHub网站,我将其内容粘贴在下面。#include <algorithm>
#include <iomanip>
#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>
#ifdef _MSC_VER
//#include "../minmax.h"
#include "minmax.h"
#else
using std::max;
#endif
using std::cin;
using std::cout;
using std::domain_error;
using std::endl;
using std::istream;
using std::ostream;
using std::setprecision;
using std::setw;
using std::sort;
using std::streamsize;
using std::string;
using std::vector;
struct Student_info {
string name;
double midterm, final;
vector<double> homework;
}; // note the semicolon--it's required
// compute the median of a `vector<double>'
// note that calling this function copies the entire argument `vector'
double median(vector<double> vec) {
#ifdef _MSC_VER
typedef std::vector<double>::size_type vec_sz;
#else
typedef vector<double>::size_type vec_sz;
#endif
vec_sz size = vec.size();
if (size == 0)
throw domain_error("median of an empty vector");
sort(vec.begin(), vec.end());
vec_sz mid = size/2;
return size % 2 == 0 ? (vec[mid] + vec[mid-1]) / 2 : vec[mid];
}
// compute a student's overall grade from midterm and final exam grades and homework grade
double grade(double midterm, double final, double homework) {
return 0.2 * midterm + 0.4 * final + 0.4 * homework;
}
// compute a student's overall grade from midterm and final exam grades
// and vector of homework grades.
// this function does not copy its argument, because `median' does so for us.
double grade(double midterm, double final, const vector<double>& hw) {
if (hw.size() == 0)
throw domain_error("student has done no homework");
return grade(midterm, final, median(hw));
}
double grade(const Student_info& s) {
return grade(s.midterm, s.final, s.homework);
}
// read homework grades from an input stream into a `vector<double>'
istream& read_hw(istream& in, vector<double>& hw) {
if (in) {
// get rid of previous contents
hw.clear();
// read homework grades
double x;
while (in >> x)
hw.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) {
// read and store the student's name and midterm and final exam grades
is >> s.name >> s.midterm >> s.final;
read_hw(is, s.homework); // read and store all the student's homework grades
return is;
}
bool compare(const Student_info& x, const Student_info& y) {
return x.name < y.name;
}
int main() {
vector<Student_info> students;
Student_info record;
string::size_type maxlen = 0;
// read and store all the records, and find the length of the longest name
while (read(cin, record)) {
maxlen = max(maxlen, record.name.size());
students.push_back(record);
}
// alphabetize the records
sort(students.begin(), students.end(), compare);
#ifdef _MSC_VER
for (std::vector<Student_info>::size_type i = 0;
#else
for (vector<Student_info>::size_type i = 0;
#endif
i != students.size(); ++i) {
// write the name, padded on the right to `maxlen' `+' `1' characters
cout << students[i].name
<< string(maxlen + 1 - students[i].name.size(), ' ');
// compute and write the grade
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;
}
main1.cc
,main2.cc
和main3.cc
的代码全部使用单个makefile
和make
语句进行编译。这是makefile
的内容。我不相信main2.cc
使用此header
中提到的任何makefile
文件,但是我没有对makefile
进行任何更改。我没有在此处粘贴任何header
文件的内容。如果它们与main2.cc
相关,我可以根据要求提供它们,也可以在上面的GitHub站点上找到它们。CXX = g++
CC = g++
all: main1 main2 main3
Student_info.o: Student_info.cc Student_info.h
grade.o: grade.cc grade.h median.h Student_info.h
main3.o: main3.cc grade.h median.h Student_info.h
median.o: median.cc median.h
main3: main3.o grade.o median.o Student_info.o
test: all
./main1 <../data/single_grade
./main2 <../data/single_grade
./main2 <../data/grades
./main3 <../data/grades
clobber:
rm -f *.o *.exe core main1 main2 main3
我创建了一个称为subfolder
的data
并将两个数据文件放入其中:grades
和single_grade
。以下是grades
的内容:Moo 100 100 100 100 100 100 100 100
Moore 75 85 77 59 0 85 75 89
Norman 57 78 73 66 78 70 88 89
Olson 89 86 70 90 55 73 80 84
Peerson 47 70 82 73 50 87 73 71
Russel 72 87 88 54 55 82 69 87
Thomas 90 96 99 99 100 81 97 97
Vaughn 81 97 99 67 40 90 70 96
Westerly 43 98 96 79 100 82 97 96
Baker 67 72 73 40 0 78 55 70
Davis 77 70 82 65 70 77 83 81
Edwards 77 72 73 80 90 93 75 90
Franklin 47 70 82 73 50 87 73 71
Jones 77 82 83 50 10 88 65 80
Harris 97 90 92 95 100 87 93 91
Smith 87 92 93 60 0 98 75 90
Carpenter 47 90 92 73 100 87 93 91
Fail1 45 55 65 80 90 70 65 60
Fail2 55 55 65 50 55 60 65 60
以下是single_grade
的内容:harriet 85 95 88 87 93 45 76 99
在上面的任何代码中,我唯一找到的这两个数据文件是在makefile
中,这使我感到困惑,但是我猜makefile
将main2.cc
与这两个数据文件相关联。以下是
"minmax.h"
的内容:/**
* This file has no copyright assigned and is placed in the Public Domain.
* This file is part of the mingw-w64 runtime package.
* No warranty is given; refer to the file DISCLAIMER.PD within this package.
*/
#ifndef _INC_MINMAX
#define _INC_MINMAX
#ifndef __cplusplus
#ifndef NOMINMAX
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
#endif
#endif
#endif
这是我的c++ -v
笔记本电脑上的Windows 10
返回的内容:c:\Users\mark_\myCppprograms>c++ -v
Using built-in specs.
COLLECT_GCC=c++
COLLECT_LTO_WRAPPER=c:/rtools/MINGW_64/bin/../libexec/gcc/x86_64-w64-mingw32/4.9.3/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: ../../../src/gcc-4.9.3/configure --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --prefix=/mingw64 --with-sysroot=/home/Jeroen/mingw-gcc-4.9.3/x86_64-493-posix-seh-rt_v3-s/mingw64 --with-gxx-include-dir=/mingw64/x86_64-w64-mingw32/include/c++ --enable-static --disable-shared --disable-multilib --enable-languages=c,c++,fortran,lto --enable-libstdcxx-time=yes --enable-threads=posix --enable-libgomp --enable-libatomic --enable-lto --enable-graphite --enable-checking=release --enable-fully-dynamic-string --enable-version-specific-runtime-libs --disable-isl-version-check --disable-cloog-version-check --disable-libstdcxx-pch --disable-libstdcxx-debug --enable-bootstrap --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch=nocona --with-tune=core2 --with-libiconv --with-system-zlib --with-gmp=/home/Jeroen/mingw-gcc-4.9.3/prerequisites/x86_64-w64-mingw32-static --with-mpfr=/home/Jeroen/mingw-gcc-4.9.3/prerequisites/x86_64-w64-mingw32-static --with-mpc=/home/Jeroen/mingw-gcc-4.9.3/prerequisites/x86_64-w64-mingw32-static --with-isl=/home/Jeroen/mingw-gcc-4.9.3/prerequisites/x86_64-w64-mingw32-static --with-cloog=/home/Jeroen/mingw-gcc-4.9.3/prerequisites/x86_64-w64-mingw32-static --enable-cloog-backend=isl --with-pkgversion='x86_64-posix-seh, Built by MinGW-W64 project' --with-bugurl=http://sourceforge.net/projects/mingw-w64 CFLAGS='-O2 -pipe -I/home/Jeroen/mingw-gcc-4.9.3/x86_64-493-posix-seh-rt_v3-s/mingw64/opt/include -I/home/Jeroen/mingw-gcc-4.9.3/prerequisites/x86_64-zlib-static/include -I/home/Jeroen/mingw-gcc-4.9.3/prerequisites/x86_64-w64-mingw32-static/include' CXXFLAGS='-O2 -pipe -I/home/Jeroen/mingw-gcc-4.9.3/x86_64-493-posix-seh-rt_v3-s/mingw64/opt/include -I/home/Jeroen/mingw-gcc-4.9.3/prerequisites/x86_64-zlib-static/include -I/home/Jeroen/mingw-gcc-4.9.3/prerequisites/x86_64-w64-mingw32-static/include' CPPFLAGS= LDFLAGS='-pipe -L/home/Jeroen/mingw-gcc-4.9.3/x86_64-493-posix-seh-rt_v3-s/mingw64/opt/lib -L/home/Jeroen/mingw-gcc-4.9.3/prerequisites/x86_64-zlib-static/lib -L/home/Jeroen/mingw-gcc-4.9.3/prerequisites/x86_64-w64-mingw32-static/lib '
Thread model: posix
gcc version 4.9.3 (x86_64-posix-seh, Built by MinGW-W64 project)
c:\Users\mark_\myCppprograms>
我知道其他人已经上传了加速C++练习的解决方案。我看了几个。但是我无法让它们中的任何一个与main2.cc
或main3.cc
一起运行并返回预期的结果。 最佳答案
我不确定您实际如何运行它,但就我而言,它运行得很好。如果仔细查看main
中的main2.cc
,您会注意到存在一个阻塞的read
调用,这导致程序等待用户输入。看一下makefile中的test
目标:
test: all
./main1 <../data/single_grade
./main2 <../data/single_grade
./main2 <../data/grades
./main3 <../data/grades
<
意味着我们将single_grade
中的内容重定向到正在运行的进程。隐式假定可执行二进制文件上方的文件夹中将是data
目录和single_grade
数据文件。因此,当您运行$ make test
时,您会注意到一切正常(假设目录结构未更改)。如果仅运行$ ./main2
,则在程序等待输入时将不会发生任何事情。或者,假设您的数据文件位于main2
二进制文件旁边,则可以运行$ main2 < single_grade
。或者,您也可以完全省略文件:$ ./main2
$ Moo 100 100 100 100 100 100 100 100
$ Moore 75 85 77 59 0 85 75 89
$ EOF (in bash shell it's CTRL + D, on windows cmd: CTRL + Z)
产生:Moo 100
Moore 79.4
关于c++ - 加速C++练习4-0,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/63766533/