c++primer Chapter 8 (problem solving): IO Library

Keywords: C++

Section 8.1.2 exercise

8.1: write a function, accept an istream & parameter, and the return value type is istream &. This function must read data from the given stream. Stop until the end of the file is encountered. It prints the read data on your standard input. After these operations are completed, the convection is reset to a valid state before returning to the flow.
Answer:

istream& ret(istream& is) {
	string a;
	while (is>>a) {
		cout << a;
	}
	is.clear();
	return is;
}

8.2: test function, call parameter is cin.

#include<iostream>
using namespace std;
istream& ret(istream& is) {
	string a;
	while (is>>a) {
		cout << a;
	}
	is.clear();
	return is;
}
int main() {
	ret(cin);
}

8.3: under what circumstances will the following while terminate?
while(cin>>i)/.../
A: as long as the status of the stream is wrong, it will stop. If there is a file end character or a read-write error, it will lead to a status error.

Section 8.2.1 exercise

8.4: write a function to open a file in read mode, read its contents into a string vector, and store each line in the vector as an independent element
Answer:

#include<iostream>
#include<fstream>
#include<vector>
#include<string>
using namespace std;
vector<string>ans;
void read(string file) {
	ifstream is(file, ios::in);
	if (!is.is_open()) {
		cout << "fail to read file" << endl;
	}
	string str;
	while (getline(is, str)) {
		ans.push_back(str);
	}
}
int main() {
	string file = "D:\\data.txt";
	read(file);
	for (auto a : ans) {
		cout << a << endl;
	}
	return 0;
}

8.5: rewrite the above program and store each word as an independent element.
Answer:

#include<iostream>
#include<fstream>
#include<vector>
#include<string>
using namespace std;
vector<string>ans;
void read(string file) {
	ifstream is(file, ios::in);
	if (!is.is_open()) {
		cout << "fail to read file" << endl;
	}
	string str;
	while (is>>str) {
		ans.push_back(str);
	}
}
int main() {
	string file = "D:\\data.txt";
	read(file);
	for (auto a : ans) {
		cout << a << endl;
	}
	return 0;
}

8.6: rewrite the bookstore program in section 7.1.1 (page 229) to read transaction records from a file. Pass the file name as a parameter to main
Answer:

int main(char argc,char **argv) {
	std::ifstream input(argv[1]);
	std::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;
			}
		}

	}
	else {
		cerr << "no data?!" << endl;
	}
	return 0;
}

Section 8.2.2 exercise

8.7: modify the bookstore program in the previous section and save the results to a file. Pass the output file name as the second argument to the main function
Answer: as shown in the above question
8.8: modify the program of the previous question, add the result to the end of the given file, and run the program at least twice for the same output file. Verify that the data is retained.
Answer:

//ate means it is appended to the end of the file
int main(char argc,char **argv) {
	std::ifstream input(argv[1]);
	std::ofstream output(argv[2],ofstream::ate);
	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;
			}
		}

	}
	else {
		cerr << "no data?!" << endl;
	}
	return 0;
}

Section 8.3.1 exercise

8.9: print the contents of an istringstream object using the function you wrote for the first exercise in section 8.1.2.
Answer:

//Remember to add the sstream header file
int main() {
	string str="hello world";
	istringstream record(str);
	ret(record);
	return 0;
}

8.10: write a program to save lines from a file in a vector < string >, and then use an istringstream to read data elements from the vector, one word at a time.
Answer:

int main() {
	string input_file="D:\\data.txt";
	ifstream in(input_file);
	string line;
	vector<string>data;
	while (getline(in, line)) {
		data.push_back(line);
	}
	string output;
	for (auto& str : data) {
		istringstream istring(str);
		/*test*/while (istring >> output) {
			cout << output << endl;
		}
	}
	return 0;
}

8.11: the program in this article defines the istringstream object in the outer while. If the record object is defined outside the loop, what changes do you need to make to the program? Rewrite the program and move the definition of record out of the while loop to verify whether the modification method you envisaged is correct.
Answer:

int main() {
	string line, word;
	vector<PersonInfo>people;
	istringstream record(line);
	while (getline(cin, line)) {
		PersonInfo info;
		record.str(line);
		record >> info.name;
		while (record >> word)
			info.phone.push_back(word);
		people.push_back(info);
		record.clear();//Be careful to reset the status
	}
	for (int i = 0; i < people.size(); i++) {
		cout << people[i].name << endl;
		for (auto& phones : people[i].phone) {
			cout << phones << endl;
		}
	}
	return 0;
}

8.12: why don't we use class initialization in PersonInfo?
A: the number of telephone numbers of each person is uncertain. It's better to set the person's name and add the number in the program.

Section 8.3.2 exercise

Rewrite the phone number program in this section to read data from a named file instead of cin.
Answer:

string line, word;
	vector<PersonInfo>people;
	istringstream record(line);
	string input_file = "D:\\data.txt";
	ifstream in(input_file);//It's changed here
	while (getline(in, line)) {
		PersonInfo info;
		record.str(line);
		record >> info.name;
		while (record >> word)
			info.phone.push_back(word);
		people.push_back(info);
		record.clear();
	}
	for (int i = 0; i < people.size(); i++) {
		cout << people[i].name << endl;
		for (auto& phones : people[i].phone) {
			cout << phones << endl;
		}
	}
	return 0;
}

8.14: why do we define entry and num as const auto&?
A: prevent modification of its data

Posted by neds75 on Tue, 14 Sep 2021 13:59:59 -0700