Skip to content

Commit

Permalink
Merge pull request pezy#75 from cheng668/master
Browse files Browse the repository at this point in the history
Exercise 17.22
  • Loading branch information
pezy committed Sep 12, 2016
2 parents c5587b6 + 9958a57 commit 909c947
Showing 1 changed file with 131 additions and 0 deletions.
131 changes: 131 additions & 0 deletions ch17/ex17.22/ex17.22/main.cpp
Original file line number Diff line number Diff line change
@@ -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<iostream>
using std::cerr;
using std::cout;
using std::cin;
using std::endl;
using std::istream;
using std::ostream;

#include<fstream>
using std::ifstream;
using std::ofstream;

#include<sstream>
using std::istringstream;
using std::ostringstream;

#include<string>
using std::string;

#include<vector>
using std::vector;

#include <regex>
using std::regex;
using std::sregex_iterator;
using std::smatch;

struct PersonInfo {
string name;
vector<string> phones;
};

bool valid(const smatch& m);
void read_record(istream& is, ostream& ou, vector<PersonInfo>& 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<PersonInfo> people;

string filename;
cout << "Please input a record file name: ";
cin >> filename;
cout << endl;
ifstream fin(filename);

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<PersonInfo>& 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;
}

0 comments on commit 909c947

Please sign in to comment.