(C++ Primer Plus课后编程练习第6章参考代码)
声明:
作者入门小白,将学习过程中的代码做一些分享,仅供大家参考,欢迎大家交流指正。全部编译运行过,水平有限,不喜勿喷。
环境:
Windows 7操作系统,Dev C++ 5.11,TDM-GCC 4.9.2 64-bit Release
1.编写一个小程序,读取键盘输入,知道遇到@符号为止,并回显输入(数字除外),同时将大写字符转换为小写,将小写字符转换为大写(别忘了cctype函数系列)。
代码:
#include <iostream>
#include <cctype> //使用isdigit()、toupper()等需包含此头文件
using namespace std;
int main()
{
cout << "Please input characters:" << endl;
char ch;
while( (ch=cin.get()) && ch!='@' ) //遇到@符号退出
{
if( islower(ch) ) //小写转换为大写
cout << (char)toupper(ch);
else if( isupper(ch) ) //大写转换为小写
cout << (char)tolower(ch);
else if( isdigit(ch) ) //数字不显示
continue;
else //其他字符原样输出
cout << ch;
}
cout << "\nBye" << endl; //程序结束提示语
return 0;
}
结果:
2.编写一个程序最多将10个donation值读入到一个double数组中(如果愿意,也可以使用模板类array)。程序遇到非数字输入时结束输入,并报告这些数字的平均值以及数组中有多少个数字大于平均值。
代码:
#include <iostream>
using namespace std;
const int Max = 10; //最多元素个数10个
int main()
{
cout << "Please input max 10 value:" << endl;
double donation[Max] = {0.0}; //声明double数组并初始化
double sum, average; //sum为和,average为平均数
int cnt, count; //cnt为输入的有效元素的个数,count为大于平均数的元素个数
sum = average = 0.0; //初始化
cnt = count = 0;
for( int i=0; i<Max; i++ ) //最多读取10个数据
{
if( cin >> donation[i] ) //若成功以double格式读取,cin>>donation[i]将返回非0值
{
sum += donation[i]; //对有效元素求和
cnt++; //统计有效元素个数
cout << donation[i] << ","; //输出成功读入的元素
}
else break; //输入非数字时结束输入
}
cout << "\nsum: " << sum << endl; //输出和
if( cnt>0 ) //vnt作为除数,不能为0
{
average = sum/cnt; //求平均值
cout << "average: " << average << endl;
for( int j=0; j<cnt; j++ ) //遍历有效元素
{
if( donation[j]>average ) //统计大于平均数的元素个数
count++;
}
cout << "number of upper average: " << count << endl;
}
cout << "Done" << endl; //结束语
return 0;
}
结果:
3.编写一个菜单驱动程序的雏形。该程序显示一个提供4个选项的菜单–每个选项用一个字母标记,如果用户使用有效选项之外的字母进行响应,程序将提示用户输入一个有效的字母,直到用户这样做为止。该程序使用一条switch语句,根据用户的选择执行一个简单操作。
代码:
#include <iostream>
#include <cctype>
using namespace std;
int main()
{
cout << "Please enter one of the following choices:\n"
<< "c) carnivore p) pianist\n"
<< "t) tree g) game\n";
char ch;
cin >> ch;
while( ch!='c' && ch!='p' && ch!='t' && ch!='g' ) //直到输入正确的指令时结束循环
{
cout << "Please enter a c, p, t, or g: ";
cin >> ch;
}
switch( ch ) //根据输入选择执行一个输出语句
{
case 'c': cout << "Tiger is carnivore.\n"; break;
case 'p': cout << "Langlang is a pianist.\n"; break;
case 't': cout << "A maple is tree.\n"; break;
case 'g': cout << "LOL is a game.\n"; break;
}
cout << "Done" << endl;
return 0;
}
结果:
4.加入Benevolent Orderof Programmer后,在BOP大会上,人们便可以通过加入者的真实姓名、头衔或秘密BOP姓名来了解他(她)。请编写一个程序,可以使用真实姓名、头衔、秘密姓名或成员偏好来列出成员。该程序创建一个由结构体组成的小型数组,并将其初始化为合适的值。另外,该程序使用一个循环,让用户在选项中进行选择。
代码:
#include <iostream>
using namespace std;
const int strsize = 20; //字符数组最大字符数
struct bop //声明bop结构
{
char fullname[strsize]; //full name
char title[strsize]; //job title
char bopname[strsize]; //secret BOP name
int preference; //0=fullname,1=title,2=bopname
};
int main()
{
bop people[5] = //声明具有5个bop结构元素的数组并初始化
{
{"Wimp Macho", "", "", 0},
{"Raki Rhodes", "Junior Programmer", "", 1},
{"Celia Laiter", "", "MIPS", 2},
{"Hoppy Hipman", "Analyst Trainee", "", 1},
{"Pat Hand", "", "LOOPY", 2}
};
cout << "Benevolent Order of Programmers Report:\n"
<< "a) display by name b) display by title\n"
<< "c) display by bopname d) display bby preference\n"
<< "q) quit\n";
cout << "Enter your choices: ";
char ch;
cin >> ch;
while( ch!='q' ) //当输入字符‘q’时退出
{
switch( ch ) //分别按用户指定方式列出成员
{
case 'a': for( int i=0; i<5; i++ ) cout << people[i].fullname << endl; break;
case 'b': for( int i=0; i<5; i++ ) cout << people[i].title << endl; break;
case 'c': for( int i=0; i<5; i++ ) cout << people[i].bopname << endl; break;
case 'd':
{
for( int i=0; i<5; i++ ) //根据偏好列出成员
{
if( people[i].preference==0 )
cout << people[i].fullname << endl;
else if( people[i].preference==1 )
cout << people[i].title << endl;
else if( people[i].preference==2 )
cout << people[i].bopname << endl;
}
}break;
}
cout << "Next choices: "; //输入提示
cin >> ch;
}
cout << "Bye!" << endl; //结束语
return 0;
}
结果:
5.在Neutronia王国,货币单位是tvarp,收入所得税的计算方式如下:5000tvarps不收税、5001—15000tvarps10%、15001—35000tvarps15%、35000tvarps以上20%。例如收入为38000tvarps时,所得税5000X0.00+10000X0.1+20000X0.15+3000X0.2,即4600tvarps。请编写一个程序,使用循环来要求用户输入收入,并报告所得税。当用户输入负数或者非数字时,循环将结束。
代码:
#include <iostream>
using namespace std;
const double rate1 = 0.1; //各区间的税率
const double rate2 = 0.15;
const double rate3 = 0.2;
int main()
{
cout << "Please enter your income: ";
double income;
while( (cin>>income) && (income>=0) ) //当输入负数或者非数字时结束循环
{
cout << "Your income: " << income << endl;
double tax = 0.0; //总税额
double buf = income; //使用buf取代income进行操作,防止income被改变
while( buf>5000 ) //不高于5000时不用交税
{
if( buf>=35001 ) //大于35000时
{
tax += (buf-35000.0) * rate3; //税额=超出部分*税率
buf -= (buf-35000.0); //余下税额按buf=35000计算
}
else if( buf>=15001 && buf<=35000 ) //15001~35000
{
tax += (buf-15000.0) *rate2;
buf -= (buf-15000.0); //余下税额按buf=15000计算
}
else if( buf>=5001 && buf<=15000 ) //5001~15000
{
tax += (buf-5000.0) * rate1;
buf -= (buf-5000.0); //余下税额按buf=5000计算
}
}
cout << fixed; //使用定点小数表示法
cout.precision(2); //精确小数点后2位
cout.setf(ios_base::showpoint); //为整数时也显示小数点
cout << "Your tax: " << tax << endl;
cout << "Please enter your income: ";
}
cout << "Done!" << endl; //结束语
return 0;
}
结果:
6.编写一个程序,记录捐给“维护合法权益群体”的资金。该程序要求用户输入捐献者数目,然后要求用户输入每一个捐献者的姓名和款项。这些信息存储在一个动态分配的结构数组中。每个结构有两个成员:用来存储姓名的字符数组(或string对象)和用来存储款项的double成员。读取所有数据后,程序将显示所有捐款超过10000的捐款者的姓名及其捐款数额。该列表前应包含一个标题,指出下面的捐款者是重要捐款人(Grand Patrons)。然后程序列出其他捐款者,该列表以Patrons开头。如果某种类别没有捐款者,则程序将打印“none”。该程序只显示这两种类别而不进行排序。
代码:
#include <iostream>
using namespace std;
struct Donation //声明Donation结构
{
char name[20]; //姓名
double money; //捐款数额
};
int main()
{
cout << "Please input the number of people: ";
int num = 0;
cin >> num; //获取捐献者数目
cin.get(); //消除数字末尾的回车
Donation *people = new Donation [num]; //动态分配结构数组
cout << "Enter " << num << " people information:" << endl;
for( int i=0; i<num; i++ ) //获取捐赠者信息
{
cout << "People " << i+1 << " name: ";
cin.getline(people[i].name, 20);
cout << "People " << i+1 << " money: ";
cin >> people[i].money;
cin.get();
}
cout << endl << "-------Grand Patrons:-------" << endl;
int cnt = 0; //Grand Patrons人数
for( int i=0; i<num; i++ ) //输出Grand Patrons
{
if( people[i].money>=10000 )
{
cout << people[i].name << "\t\t" << people[i].money << endl;
cnt++;
}
}
if( cnt==0 )
cout << "none\n"; //若无,输出none
cout << endl << "----------Patrons:----------" << endl;
int count = 0;
for( int i=0; i<num; i++ ) //输出Patrons
{
if( people[i].money<10000 )
{
cout << people[i].name << "\t\t" << people[i].money << endl;
count++;
}
}
if( count==0 )
cout << "none\n"; //若无,输出none
delete [] people; //释放内存
cout << "\nDone!" << endl; //结束语
return 0;
}
结果:
7.编写一个程序,它每次读取一个单词,直到用户只输入q。然后,该程序指出有多少个单词以元音打头,有多少单词以辅音打头,还有多少单词不属于这两类。为此,方法之一是使用isalpha()来区分以字母和其他字符打头的单词,然后对于通过了isalpha()测试的单词,使用if或switch语句来确定哪些以元音打头。
代码:
#include <iostream>
#include <cstring> //使用strcpy()需包含此头文件
#include <cctype> //使用isalpha()需包含此头文件
using namespace std;
int main()
{
int vowels = 0; //元音字母开头的单词数
int consonants = 0; //辅音字母开头的单词数
int others = 0; //其他开头的单词数
cout << "Enter words (q to quit):" << endl;
char str[20]; //一个单词最长20个字母组成
int cnt = 0; //单词总数
cin >> str;
while( strcmp(str, "q") ) //输入q时退出
{
if( !isalpha(str[0]) ) //若不是字母开头,则为其他字符开头
others++;
else
{
switch( str[0] ) //开头字母若是元音,则vowels++
{ //其他皆是辅音,则consonants++
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
case 'A':
case 'E':
case 'I':
case 'O':
case 'U': vowels++; break;
default : consonants++; break;
}
}
cnt++; //单词总数cnt++
cin >> str;
}
cout << vowels << " words beginning with vowels\n";
cout << consonants << " words beginning with consonants\n";
cout << others << " others\n";
cout << cnt << " words\n";
cout << "\nDone!" << endl;
return 0;
}
结果:
8.编写一个程序,它打开一个文件文件,逐个字符地读取该文件,直到到达文件末尾,然后指出该文件中包含多少个字符。
代码:
#include <iostream>
#include <fstream> //文件操作需包含此头文件
#include <cstdlib> //使用exit()需包含此头文件
using namespace std;
int main()
{
ifstream infile; //声明infile对象
infile.open("in.txt"); //将infile对象与in.txt相关联
if( !infile.is_open() ) //若未成功打开则输出提示语
{ //该文件应与源程序在同一路径下
cout << "Read Fail!\n";
exit(EXIT_FAILURE);
}
char ch;
int cnt = 0; //统计字符个数
ch = infile.get(); //获取字符个数(包括空格、换行符等)
while( infile.good() ) //若成功获取到字符,则继续读取下一字符
{ //若不成功,则退出循环
cout << ch;
cnt++;
ch = infile.get(); //若获取单词个数,将ch=infile.get()改为
} //cin >> infile
if( infile.eof() ) //若不成功原因是到达文件末尾,输出提示语
cout << endl << "File end!";
infile.close(); //关闭文件
cout << endl << cnt << " characters ." << endl;
return 0;
}
结果:
9.完成练习6,但从文件中读取所需的信息。该文件的第一项应为捐款人数,余下的内容应为成对的行。在每一对中,第一行为捐款人姓名,第二行为捐款数额。
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cstring>
using namespace std;
struct Donation //声明Donation结构
{
char name[20]; //姓名
double money; //捐款数额
};
int main()
{
ifstream infile;
infile.open("in.txt");
if( !infile.is_open() )
{
cout << "Read Fail!\n";
exit(EXIT_FAILURE);
}
int num;
infile >> num;
while( !infile.good() );
cout << "Success! num: " << num << endl;
infile.get(); //读取换行符
Donation *people = new Donation [num];
char str[50];
int dig;
int i = 0;
infile.getline( str, 50 ); //获取字符串
while( infile.good() && (i<num) ) //成功读取且个数不超过人数
{
strcpy( people[i].name, str ); //将读取到的字符串复制到对应结构体的name中
infile >> dig; //获取数字
people[i].money = dig; //将读取到的数字复制到对应结构体的money中
infile.get(); //读取数字结尾的换行符
i++; //下标i递增
infile.getline( str, 50 ); //获取字符串
}
if( infile.eof() )
cout << "\nFile end!\n"; //到达文件末尾时提示
cout << endl << "-------Grand Patrons:-------" << endl;
int cnt = 0; //Grand Patrons人数
for( int j=0; j<num; j++ ) //输出Grand Patrons
{
if( people[j].money>=10000 )
{
cout << people[j].name << "\t\t" << people[j].money << endl;
cnt++;
}
}
if( cnt==0 )
cout << "none\n"; //若无,输出none
cout << endl << "----------Patrons:----------" << endl;
int count = 0;
for( int j=0; j<num; j++ ) //输出Patrons
{
if( people[j].money<10000 )
{
cout << people[j].name << "\t\t" << people[j].money << endl;
count++;
}
}
if( count==0 )
cout << "none\n"; //若无,输出none
infile.close(); //关闭文件
delete [] people; //释放内存
cout << "\nDone!" << endl; //结束语
return 0;
}
结果: