From e6d4f886d9b0652317bf2462609a33daacfc3db7 Mon Sep 17 00:00:00 2001 From: cheng668 <414866271@qq.com> Date: Sat, 10 Sep 2016 15:34:12 +0800 Subject: [PATCH 1/2] Exercise 17.22 --- ch17/ex17.22/ex17.22/main.cpp | 131 ++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 ch17/ex17.22/ex17.22/main.cpp diff --git a/ch17/ex17.22/ex17.22/main.cpp b/ch17/ex17.22/ex17.22/main.cpp new file mode 100644 index 00000000..bdde81b3 --- /dev/null +++ b/ch17/ex17.22/ex17.22/main.cpp @@ -0,0 +1,131 @@ +/*************************************************************************** +* @file main.cpp +* @author Cheng668 +* @date 10 Sept 2016 +* @remark This code is for the exercises from C++ Primer 5th Edition +* @note +***************************************************************************/ +//! +//! Exercise 17.22 +//! Rewrite your phone program so that it allows any number +//! of whitespace characters to separate the three parts of a phone number. + +#include +using std::cerr; +using std::cout; +using std::cin; +using std::endl; +using std::istream; +using std::ostream; + +#include +using std::ifstream; +using std::ofstream; + +#include +using std::istringstream; +using std::ostringstream; + +#include +using std::string; + +#include +using std::vector; + +#include +using std::regex; +using std::sregex_iterator; +using std::smatch; + +struct PersonInfo { + string name; + vector phones; +}; + +bool valid(const smatch& m); +void read_record(istream& is, ostream& ou, vector& people); +void format_record(ostream& os, const string& str, PersonInfo& people); +//! fake function that makes the program compile +string format(const string &num) { return num; } + +int main() +{ + vector people; + + string filename; + //cout << "Please input a record file name: "; + //cin >> filename; + //cout << endl; + ifstream fin(".//test.txt"); + + if (fin.is_open()) + { + ofstream fout("data\\result.txt", ofstream::trunc); + read_record(fin, fout, people); + } + else + { + cout << "Fail to open file " << filename << endl; + } + system("pause"); + return 0; +} + +bool valid(const smatch& m) +{ + //! if there is an open parenthesis before the area code + if (m[1].matched) + //! the area code must be followed by a close parenthesis + //! and followed immediately by the rest of the number or a space + return m[3].matched + && (m[4].matched == 0 || m[4].str() == " "); + else + //! then there can't be a close after the area code + //! the delimiters between the other two components must match + return !m[3].matched + && m[4].str() == m[6].str(); +} + +void read_record(istream& is,ostream& os, vector& people) +{ + string line, word; //! will hold a line and word from input, respectively + //! read the input a line at a time until cin hits end-of-file (or another error) + while (getline(is, line)) + { + PersonInfo info; //! create an object to hold this record's data + istringstream record(line); //! bind record to the line we just read + record >> info.name; //! read the name + while (getline(record, word)) //! read all the phone numbers includes the space character + format_record(os,word,info); + people.push_back(info); //! append this record to people + } + return; +} + +void format_record(ostream& os, const string& phones, PersonInfo& people) +{ + string phone = + "(\\()?(\\d{3})(\\))?([-.]|\\s*)?(\\d{3})([-.]|\\s*)?(\\d{4})\\b"; + regex r(phone); + ostringstream formatted, badNums; //! objects created on each loop + for (sregex_iterator it(phones.begin(), phones.end(), r), end_it; + it != end_it; ++it) + { + //! check whether the number's formatting is valid + if (!valid(*it)) + //! string in badNums + badNums << " " << it->str(); + else + {//! "writes" to formatted's string + formatted << " " << format(it->str()); + people.phones.push_back(it->str());//!record the vaild phones + } + } + + if (badNums.str().empty()) //! there were no bad numbers + os << people.name << " " //! print the name + << formatted.str() << endl; //! and reformatted numbers + else //! otherwise, print the name and bad numbers + cerr << "input error: " << people.name + << " invalid number(s) " << badNums.str() << endl; +} \ No newline at end of file From 9958a5719338dae74d269ced6a939df15ffd8881 Mon Sep 17 00:00:00 2001 From: cheng668 <414866271@qq.com> Date: Sat, 10 Sep 2016 15:43:17 +0800 Subject: [PATCH 2/2] Update main.cpp --- ch17/ex17.22/ex17.22/main.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ch17/ex17.22/ex17.22/main.cpp b/ch17/ex17.22/ex17.22/main.cpp index bdde81b3..2dcf60d1 100644 --- a/ch17/ex17.22/ex17.22/main.cpp +++ b/ch17/ex17.22/ex17.22/main.cpp @@ -53,10 +53,10 @@ int main() vector people; string filename; - //cout << "Please input a record file name: "; - //cin >> filename; - //cout << endl; - ifstream fin(".//test.txt"); + cout << "Please input a record file name: "; + cin >> filename; + cout << endl; + ifstream fin(filename); if (fin.is_open()) { @@ -128,4 +128,4 @@ void format_record(ostream& os, const string& phones, PersonInfo& people) else //! otherwise, print the name and bad numbers cerr << "input error: " << people.name << " invalid number(s) " << badNums.str() << endl; -} \ No newline at end of file +}