练习8.13:重写本节的电话号码程序, 从一个命名文件而非cin读取数据。
解答:
#include<iostream>
#include<sstream>
#include<fstream>
#include<string>
#include<vector>
using std::cout;using std::endl;using std::string;using std::vector;
using std::ifstream;using std::istringstream;using std::cerr;using std::isdigit;
struct PersonInfo{
string name;
vector<string> phones;
};
bool valid(const string& str)
{
return isdigit(str[0]);
}
string format(const string& str)
{
return (str.substr(0,3)+"-"+str.substr(3,3)+"-"+str.substr(6));
}
int main()
{
string line,word;
ifstream ifs("phonenumber.txt");
if(!ifs)
{
cerr<<"No phone numbers?"<<endl;
return -1;
}
vector<PersonInfo> people;
istringstream record;
while(getline(ifs,line))
{
PersonInfo info;
record.clear();
record.str(line);
record>>info.name;
while(record>>word)
info.phones.push_back(word);
people.push_back(info);
}
for(const auto &entry:people)
{
std::ostringstream formatted,badNums;
for(const auto &nums:entry.phones)
if(!valid(nums))
badNums<<" "<<nums;
else
formatted<<" "<<format(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;
}
练习8.14:我们为什么将entry和nums定义为const auto&?
解答:因为他们都是类类型,而不是内置类型。所以参考更有效;输出不应该改变他们的值。所以我们添加const。