Chapter 8 The IO Library
Exercise 8.1: Write a function that takes and returns an istream&
. The function should read the stream until it hits end-of-file. The function should print what it reads to the standard output. Reset the stream so that it is valid before returning the stream.
std::istream &exercise81(std::istream &is) {
string data;
while (is >> data) {
cout << data;
}
is.clear();
assert(is.good());
return is;
}
Exercise 8.2: Test your function by calling it, passing cin
as an argument.
Exercise 8.3: What causes the following while to terminate?
while (cin >> i) /* ... */
---
// CTRL+D/CTRL+C,end-of-file或者signal,或者读入非i类型的数据,导致流出错,循环终止。
Exercise 8.4: Write a function to open a file for input and read its contents into avector of strings, storing each line as a separate element in the vector.
#include <iostream>
#include <fstream>
#include <vector>
using std::cerr; using std::cout; using std::endl;
using std::ifstream;
using std::string; using std::vector; using std::getline;
int main(int argc, char *argv[]) {
vector<string> content;
ifstream input(argv[1]);
string line;
while (getline(input, line)) {
content.push_back(line);
}
// cout
for (const auto &l:content) {
cout << l << endl;
}
return 0;
}
Exercise 8.5: Rewrite the previous program to store each word in a separate element.
#include <iostream>
#include <fstream>
#include <vector>
using std::cerr; using std::cout; using std::endl;
using std::ifstream;
using std::string; using std::vector; using std::getline;
int main(int argc, char *argv[]) {
vector<string> content;
ifstream input(argv[1]);
string word;
while (input >> word) {
content.push_back(word);
}
// cout
for (const auto &w:content) {
cout << w << endl;
}
return 0;
}
Exercise 8.6: Rewrite the bookstore program from § 7.1.1 (p. 256) to read its transac-tions from a file. Pass the name of the file as an argument to main (§ 6.2.5, p. 218).
#include "Sales_data.h"
#include <fstream>
using std::cerr; using std::cin; using std::cout; using std::endl;
using std::ifstream; using std::ofstream;
int main(int argc, char *argv[]) {
Sales_data data1, data2;
ifstream in(argv[1]);
if (read(in, data1) && read(in, data2)) { // read the transactions
if (data1.isbn() == data2.isbn()) { // check isbns
Sales_data sum = add(data1, data2); // add the transactions
print(cout, sum); // print the results
cout << endl; // followed by a newline
}
} else
cerr << "Input failed!" << endl;
return 0;
}
Exercise 8.7: Revise the bookstore program from the previous section to write its out-put to a file. Pass the name of that file as a second argument to main.
#include "Sales_data.h"
#include <fstream>
using std::cerr; using std::cin; using std::cout; using std::endl;
using std::ifstream; using std::ofstream;
int main(int argc, char *argv[]) {
Sales_data data1, data2;
ifstream in(argv[1]);
ofstream out(argv[2]);
if (read(in, data1) && read(in, data2)) { // read the transactions
if (data1.isbn() == data2.isbn()) { // check isbns
Sales_data sum = add(data1, data2); // add the transactions
print(out, sum); // print the results
out << endl; // followed by a newline
}
} else
cerr << "Input failed!" << endl;
return 0;
}
Exercise 8.8: Revise the program from the previous exercise to append its output to its given file. Run the program on the same output file at least twice to ensure that the data are preserved.
ofstream out(argv[2], ofstream::app);
Exercise 8.9: Use the function you wrote for the first exercise in § 8.1.2 (p. 314) to print the contents of an istringstream
object.
cout << "exercise 8.9: " << endl;
istringstream test("hello world!!\n");
exercise81(test);
Exercise 8.10: Write a program to store each line from a file in a vector<string>
. Now use an istringstream
to read each element from the vector a word at a time.
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
using std::cin; using std::cout; using std::cerr;
using std::istream; using std::ostream; using std::endl;
using std::ostringstream; using std::istringstream;
using std::vector; using std::string;
using std::ifstream;
int main(int argc, char *argv[]) {
vector<string> content;
string line;
// read from file
ifstream is(argv[1]);
while (std::getline(is, line)) {
content.push_back(line);
}
// read from vector
string word;
for (const auto &l :content) {
istringstream ss(l);
while (ss >> word) {
cout << word << " ";
}
cout << '\n';
}
return 0;
}
Exercise 8.11: The program in this section defined its istringstream
object inside the outer while loop. What changes would you need to make if record were defined outside that loop? Rewrite the program, moving the definition of record outside the while, and see whether you thought of all the changes that are needed.
vector<PersonInfo> getData(istream &is) {
// will hold a line and word from input, respectively
string line, word;
// will hold all the records from the input
vector<PersonInfo> people;
istringstream record;
// read the input a line at a time until end-of-file (or other error)
while (getline(is, line)) {
PersonInfo info; // object to hold this record's data
record.str(line); // bind record to the line we just read
record >> info.name; // read the name
while (record >> word) // read the phone numbers
info.phones.push_back(word); // and store them
people.push_back(info); // append this record to people
record.clear();
}
return people;
}
// 需要将流的状态复位,因为上次循环达到了EOF状态
Exercise 8.12: Why didn’t we use in-class initializers in PersonInfo
?
// 因为数据总是需要从外部读入,没有必要。
Exercise 8.13: Rewrite the phone number program from this section to read from a named file rather than from cin
.
int main(int argc, char *argv[]) {
std::ifstream is(argv[1]);
std::ofstream os(argv[2]);
process(os, getData(is));
return 0;
}
Exercise 8.14: Why did we declare entry and nums as const auto &
?
// 因为在处理过程中没有修改entry和nums,所以应该声明为const引用
Notes
- IO对象无拷贝或赋值