C++ Primer 中文版(第 5 版)练习解答合集
自己写的解答,如有错误之处,烦请在评论区指正!
1 & 2
#include <iostream>
#include <string>
#include <vector>
using namespace std;
istream& readAndReset(istream& is) {
string input;
while (is >> input) {
cout << input << endl;
}
is.clear();
return is;
}
int main() {
readAndReset(cin);
string input;
cin >> input;
cout << input;
return 0;
}
Windows 控制台,第一次输入 Ctrl+Z
后依然可以再读入一个 string ,然后才退出运行。
3
流已经崩溃,或者一个 IO 操作失败了,或者流到达文件结束。
4
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;
int main() {
string buffer;
vector<string> output;
ifstream input("test.cpp");
while (getline(input, buffer)) {
output.emplace_back(buffer);
}
for (auto s : output) {
cout << s << endl;
}
return 0;
}
5
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;
int main() {
string buffer;
vector<string> output;
ifstream input("test.cpp");
while (input >> buffer) { // 相比上一题只修改了这里
output.emplace_back(buffer);
}
for (auto s : output) {
cout << s << endl;
}
return 0;
}
6
#include <iostream>
#include <fstream>
#include <string>
#include "Sales_data.h"
using namespace std;
int main(int argc, char** argv) {
// for (int i = 0; i < argc; ++i) {
// printf("%s\n", argv[i]);
// }
if (argc < 2)
return -1;
ifstream input(argv[1]);
Sales_data total;
if (read(input, total)) {
Sales_data trans;
while (read(input, trans)) {
if (total.isbn() == trans.isbn()) {
total.combine(trans);
} else {
print(cout, total) << endl;
total = trans;
}
}
print(cout, total) << endl;
} else {
cerr << "No data?!" << endl;
}
return 0;
}
7
#include <iostream>
#include <fstream>
#include <string>
#include "Sales_data.h"
using namespace std;
int main(int argc, char** argv) {
if (argc < 3) {
cerr << "Please input two arguments: "
<< "input filename and output filename." << endl;
return -1;
}
ifstream input(argv[1]);
ofstream output(argv[2]);
Sales_data total;
if (read(input, total)) {
Sales_data trans;
while (read(input, trans)) {
if (total.isbn() == trans.isbn()) {
total.combine(trans);
} else {
print(output, total) << endl;
total = trans;
}
}
print(output, total) << endl;
} else {
cerr << "No data?!" << endl;
}
return 0;
}
8
#include <iostream>
#include <fstream>
#include <string>
#include "Sales_data.h"
using namespace std;
int main(int argc, char** argv) {
if (argc < 3) {
cerr << "Please input two arguments: "
<< "input filename and output filename." << endl;
return -1;
}
ifstream input(argv[1]);
// 相比上一题只需要修改这一行
ofstream output(argv[2], ofstream::app);
Sales_data total;
if (read(input, total)) {
Sales_data trans;
while (read(input, trans)) {
if (total.isbn() == trans.isbn()) {
total.combine(trans);
} else {
print(output, total) << endl;
total = trans;
}
}
print(output, total) << endl;
} else {
cerr << "No data?!" << endl;
}
return 0;
}
9
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
istream& readAndReset(istream& is) {
string input;
while (is >> input) {
cout << input << endl;
}
is.clear();
return is;
}
int main() {
string buffer;
string str("Hi my name is george.");
istringstream iss(str);
while (iss >> buffer) {
cout << buffer << endl;
}
return 0;
}
10
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
using namespace std;
int main(int argc, char** argv) {
if (argc < 2) {
cerr << "Please input the argument."
<< "(input filename)" << endl;
return -1;
}
string line, buffer;
ifstream input(argv[1]);
vector<string> datas;
while (getline(input, line)) {
datas.emplace_back(line);
}
for (string data : datas) {
istringstream iss(data);
while (iss >> buffer) {
cout << buffer << endl;
}
}
return 0;
}
11
#include <iostream>
#include <sstream>
#include <vector>
#include <string>
using namespace std;
struct PersonInfo {
string name;
vector<string> phones;
};
int main() {
string line, word;
vector<PersonInfo> people;
istringstream record;
while (getline(cin, line)) {
PersonInfo info;
record.str(line);
record >> info.name;
while (record >> word)
info.phones.push_back(word);
people.push_back(info);
record.clear();
}
for (const auto& person : people) {
cout << person.name << endl;
for (const auto& phone : person.phones) {
cout << phone << endl;
}
cout << endl;
}
return 0;
}
12
首先,在语法上,vector 和 string 类型都有自己的默认构造函数,所以不给类内初始值没有问题。其次,逻辑上讲每个人的电话号码数量未知,所以最好先默认初始化再修改名字并逐个添加电话号码。
13
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
using namespace std;
struct PersonInfo {
string name;
vector<string> phones;
};
bool valid(string phone) {
return phone.size() == 11;
}
int main(int argc, char** argv) {
if (argc < 2) {
cerr << "Please input the argument."
<< "(input filename)" << endl;
return -1;
}
string line, word;
vector<PersonInfo> people;
istringstream record;
ifstream input(argv[1]);
while (getline(input, line)) {
PersonInfo info;
record.str(line);
record >> info.name;
while (record >> word)
info.phones.push_back(word);
people.push_back(info);
record.clear();
}
for (const auto& entry : people) {
ostringstream formatted, badNums;
for (const auto &nums : entry.phones) {
if (!valid(nums)) {
badNums << " " << nums;
} else {
formatted << " " << nums;
}
}
if (badNums.str().empty()) {
cout << entry.name << " "
<< formatted.str() << endl;
} else {
cerr << "input error: " << entry.name
<< " invalid number(s) " << badNums.str() << endl;
}
}
return 0;
}
14
auto:在范围 for 语句中使用 auto 关键字,这样就不用关心容器具体是什么类型的,由编译器自行判断
引用:使用引用来避免对每一个字符串进行拷贝,提高程序效率
const:使用引用虽然提高了效率,但同时字符串有可能通过引用被修改,所以将引用设置为常量引用来保证数据安全