C++ Primer Plus(第六版)编程练习 第6章 分支语句和逻辑运算符

1. 编写一个程序,读取键盘输入,直到遇到@符号为止,并回显输入(数字除外),同时将大写字符转换为小写,将小写字符转换为大写(别忘了cctype函数系列)。

本题主要需要完成3个功能,第一是对于输入控制,遇到特殊字符结束,第二是将所有输入除去数字之后显示出来,第三是大小写之间的转换。对于第一个功能,可以设计一个循环输入,判决条件就是输入不等于@符号,判决条件成立,才进行后续操作并要求继续输入,否则就不会进行任何操作。对于第二个功能,有很多种解决方案,这里我使用的是isdigit()函数,既然题目中要求使用cctype的函数系列,那么我们就可以使用isdigit()函数来判断是否是数字,如果不是才输出,这样是数字时就不会输出了。对于第三个功能,直接使用cctype中的islower()函数+toupper()函数和isupper()函数+tolower()函数就可以了。

代码如下:

// 6.1-c.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>  
#include <cctype>  
using namespace std;
int main()
{
    cout << "Enter your input, type @ to terminate input:\n";
    char ch;
    cin.get(ch);
    while (ch != '@')
    {
	if (islower(ch))
	{
	    ch = toupper(ch);
	}
	else if (isupper(ch))
	{
	    ch = tolower(ch);
	}
	if (isdigit(ch) == false)
	{
	    cout << ch;
	}
	cin.get(ch);
    }
    cout << endl;
    system("pause");
    return 0;
}

运行结果如下图所示:


由上图可以看出,输出会直到出现@符号才结束,但是每敲一次回车程序就会显示一次。


2. 编写一个程序,最多将10个donation值读入到一个double数组中(如果您愿意,也可使用模板类array)。程序遇到非数字输入时将结束输入,并报告这些数字的平均值以及数组中有多少个数字大于平均值。

本题要求我们提示输入10个double数据,然后计算这些数的平均值,并记录有多少个大于平均值,但是要能够探测非数字值,并在出现非数字值时立刻停止输入,计算当前数值的平均值和记录大于平均值的数目。对于探测非数字值,可以使用cin.fail()函数,该函数成立的条件就是输入的内容并不是待输入变量的类型,使用一个if判断来跳出输入循环,就可以完成上述功能了。

代码如下:

// 6.2-c.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>    
using namespace std;
int main()
{
    double donation[10];
    int len, i, j;
    double sum = 0.0;
    double average; 
    int num = 0;
    double line;
    cout << "Enter 10 donation:" << endl;
    for (i = 0; i < 10; i++)
    {
	cin >> donation[i];
	if (cin.fail())
	{
	    cout << "Not a digit!\n";
	    break;
	}
	sum += donation[i];
    }
    average = sum / i;
    for (i = 0; i < 10; i++)
    {
        if (donation[i] > average)
	{
	    num++;
	}
    }
    cout << "The average = " << average << endl;
    cout << "In this array has " << num << " value(s) larger than avearge" << endl;

    system("pause");
    return 0;
}

运行结果如下图所示:

以下是全部输入数字的时候,当输入到第10个数字之后,一点回车就会自动跳出平均值等内容,不可以再输入;


以下是输入了非数字值时的情况,一旦探测到非数字值,就会马上提示,然后停止输入弹出平均值等信息;



3. 编写一个菜单驱动程序的雏形。该程序显示一个提供4个选项的菜单——每个选项用一个字母标记。如果用户使用有效选项之外的字母进行响应,程序将提示用户输入一个有效的字母,直到用户这样做为止。然后,该程序使用一条switch语句,根据用户的选择执行一个简单操作。该程序的运行情况如下:

Please enter one of the following choices:

c) carnivore            p) pianist

t) tree                     g) game

f

Please enter a c, p, t, or g: q

Please enter a c, p, t, or g: t

A maple is a tree.

本题要求编写一个菜单程序,首先提示用户相应字母,如果用户输入的不是相应的字母,就会提示用户重新输入,直到输入正确为止;其次题目要求使用switch语句来根据用户的输入进行选择。在这里,我使用cctype的isalpha函数来判断输入的是否是字母,再使用switch语句来判断输入的是否是相应的字母。

代码如下:

// 6.3.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <cctype>

int main()
{
    using namespace std;

    cout << "Please enter one of the following choices:" << endl;
    cout << "c) carnicore\t" << "p) pianist" << endl;
    cout << "t) tree\t\t" << "g) game" << endl;
    char alpha;
    cin.get(alpha);

    while (isalpha(alpha))
    {
	switch (alpha)
	{
	    case 'c': cout << "A maple is a carnivore." << endl;
		break;
	    case 'p': cout << "A maple is a pianisit." << endl;
		break;
	    case 't': cout << "A maple is a tree." << endl;
		break;
	    case 'g': cout << "A maple is a game." << endl;
		break;
	    default: cout << "Please enter a c, p, t, or g: ";
		cin.ignore();
	}
	cin.get(alpha);
    }
	
		
	
    system("pause");
    return 0;
}

运行结果如下图所示:



4. 加入Benevolent Order of Programmer后,在BOP大会上,人们便可以通过加入者的真实姓名、头衔或秘密BOP姓名了解他(她)。请编写一个程序,可以使用真实姓名、头衔、秘密姓名或成员偏好来列出成员。编写该程序时,请使用下面的结构:

// Benevolent Order of Programmer name structure 

struct bop {

    char fullname[strsize];      // real name

    char title[strsize];              // job title

    char bopname[strsize];     // secret BOP name

    int preference;                  // 0 = fullname, 1 = title, 2 = bopname

};

该程序创建一个由上述结构组成的小型数组,并将其初始化为适当的值。另外,该程序使用一个循环,让用户在下面的选项中进行选择:

a. display by name        b. display by title

c. display by bopname  d. display by preference

q. quit

注意,“display by preference”并不意味着显示成员的偏好,而是意味着根据成员的偏好来列出成员。例如,如果偏好号为1,则选择d将显示程序员的头衔。该程序的运行情况如下:

Benevolent Order Programmer Report 

a. display by name        b. display by title

c. display by bopname  d. display by preference

q. quit

Enter your choice: a

Wimp Macho

Raki Rhodes

Celia Laiter

Hoppy Hipman

Pat Hand

Next choice: d

Wimp Macho

Junior Programmer

MIPS 

Analyst Trainee

LOOPY

Next choice: q

Bye!

本题首先要求创建一个结构体,储存了真实姓名,头衔,秘密BOP姓名,然后给出4种选择,每种选择会显示不同的信息。

在这里我没有根据题意建立5个内容不同的结构数组,而是根据题目需要的输出进行了直接cout,如果希望完全按照题意来,就创建一个长度为5的结构数组,将所有的信息储存好,然后根据switch语句的判决结果,来cout不同的结构成员内容。

代码如下:

// 6.4.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>

int main()
{
    using namespace std;

    cout << "Benevolent Order of Programmers Report" << endl;
    cout << "a. display by name\t\t";
    cout << "b. display by title\n";
    cout << "c. display by bopname\t\t";
    cout << "d. display by preference\n";
    cout << "q. quit\n";

    cout << "Enter your choice:";
    char choice;
    cin >> choice;
    while (choice != 'q')
    {
	switch (choice)
	{
	    case 'a': cout << "Wimp Macho\n" << "Raki Rhodes\n" << "Celia Laiter\n";
		cout << "Hoppy Hipman\n" << "Pat Hand\n";
		break;
	    case 'd': cout << "Wimp Macho\n" << "Junior Programmer\n" << "MIPS\n" << "Analyst Trainee\n" << "LOOPY\n";
		break;
	}
	cout << "Enter your choice:";
	cin >> choice;
    }
    cout << "Bye!\n";
    system("pause");
    return 0;
}

运行结果如下图所示:



5. 在Neutronia王国,货币单位是tvarp,收入所得税的计算方式如下:

5000 tvarps:不收税

5001~15000 tvarps:10%

15001~35000 tvarps:15%

35000 tvarps以上:20%

例如,收入为38000 tvarps 时,所得税为5000*0.00+10000*0.10+20000*0.15+3000*0.20,即4600 tvarps。请编写一个程序,使用循环来要求用户输入收入,并报告所得税。当用户输入负数或非数字时,循环将结束。

本题要求循环输入收入,从而计算所得税,当输入为负数或非数字时,输入结束。对于具体的所得税计算方法,要根据输入的数值大小来判断,所以我们还是要使用switch。对于两种判断输入结束的方法,我们在循环内外各做一个判断。由于需要循环输入,而且不确定一共会输入多少个值,所以我使用while(cin>>income)循环来完成这个任务,于是在循环内部,我们只能判断输入类型正确时的情况,即输入的是数字时,我们根据income是否大于0来判断输入是否正确以及是否需要结束输入;而在循环外面,我使用cin.fail()函数来做判断非数字值,其实只要跳出了循环,就是输入了非数字值,做一个判断再输出输入错误及输入结束的提示内容,是因为如果不用这个判断,那么在循环内部判断是负数时,输入错误和输入结束的提示内容会输出两次,使用一个判断会避免这种情况。

代码如下:

// 6.5.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>

int main()
{
    using namespace std;

    cout << "Please enter your income to calculate the tax:";
    double income;
    double tax;
    int flag;
    double a1 = 0.1;
    double a2 = 0.15;
    double a3 = 0.2;
	
    while (cin >> income)
    {
	if (income >= 0)
	{
	    if (income <= 5000)
		flag = 0;
	    else if (5000 < income && income <= 15000)
		flag = 1;
	    else if (15000 < income && income <= 35000)
		flag = 2;
	    else if (35000 < income)
		flag = 3;
	    switch (flag)
	    {
		case 0: tax = 0;
		    break;
		case 1: tax = (income - 5000) * a1;
		    break;
		case 2: tax = ((income - 15000) * a2) + 1000;
		    break;
		case 3: tax = ((income - 35000) * a3) + 4000;
		    break;
	    }
	    cout << "Your tax is: " << tax << endl;
	    cout << "Please enter next income:";
	}
	else if (income < 0)
	{
	    cout << "Input fail.\nBye!\n";
	    break;
	}
    }
    if (cin.fail())
	cout << "Input fail.\nBye!\n";

    system("pause");
    return 0;
}

运行结果如下图所示:

以下是输入负数结束输入的情况:


以下是输入为非数字值结束输入的情况:



6. 编写一个程序,记录捐助给“维护合法权利团体”的资金。该程序要求用户输入捐赠者数目,然后要求用户输入每一个捐献者的姓名和款项。这些信息被储存在一个动态分配的结构数组中。每个结构有两个成员:用来储存姓名和字符数组(或string对象)和用来存储款项的double成员。读取所有的数据后,程序将显示所有捐款超过10000的捐献者的姓名及其捐款数额。该列表前应包含一个标题,指出下面的捐款者是重要捐款人(Grand Patrons)。然后,程序将列出其他的捐款者,该列表要以Patrons开头。如果某种类型没有捐献者,则程序将打印单词“none”。该程序只显示这两种类别,而不进行排序。

本题需要创建一个动态分配内存的结构数组来储存每个捐献者的姓名和款项,然后根据捐献的款项来分类,最后将所有结果显示出来。本题最复杂的是需要不断判断每个捐献者的款项是属于哪一个类别,而且捐献者的数目还不确定,所以我在这里首先要求输入捐献者的数目,然后根据这个数目来动态分配结构数组的长度,也更方便做后面的判断。在这里我连续使用两个cin函数来输入姓名以及金额,由于使用的string对象,而且输入是直接cin,所以不允许出现空格,而分隔姓名和金额,既可以是空格也可以是回车。

代码如下:

// 6.6.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include<iostream>  
#include<string>  
using namespace std;

struct donation 
{
    string name;
    double money;
};

int main() 
{
    int num;
    cout << "Please enter the number of donors: ";
    cin >> num;
    donation *d = new donation[num];
    int bigger = 0;

    for (int i = 0; i < num; i++)
    {
	cout << "Please enter the name and money:" << endl;
	cin >> d[i].name;
	cin >> d[i].money;
	if (d[i].money>10000) 
	{
	    bigger++;
	}
    }

    if (bigger > 0 && bigger < num) 
    {
	cout << "Grand Patrons" << endl;
	for (int i = 0; i < num; i++)
	{
	    if (d[i].money>10000) 
	    {
		cout << d[i].name << "\t" << d[i].money << endl;
	    }
	}
	cout << "Patrons" << endl;
	for (int i = 0; i < num; i++)
	{
	    if (d[i].money <= 10000) 
	    {
		cout << d[i].name << "\t" << d[i].money << endl;
	    }
	}
    }

    if (bigger == 0) 
    {
	cout << "Grand Patrons" << endl;
	cout << "none" << endl;
	cout << "Patrons" << endl;
	for (int i = 0; i < num; i++)
	{
	    if (d[i].money <= 10000) 
	    {
		cout << d[i].name << "\t" << d[i].money << endl;
	    }
	}
    }

    if (bigger == num)
    {
	cout << "Grand Patrons" << endl;
	for (int i = 0; i < num; i++) 
	{
	    if (d[i].money>10000) 
	    {
		cout << d[i].name << "\t" << d[i].money << endl;
	    }
	}
	cout << "Patrons" << endl;
	cout << "none" << endl;
    }
    delete[]d;

    system("pause");
    return 0;
}

运行结果如下图所示:



7. 编写一个程序,它每次读取一个单词,直到用户只输入q。然后,该程序指出有多少个单词以元音打头,有多少个单词以辅音打头,还有多少个单词不属于这两类。为此,方法之一是,使用isalpha()来区分字母和其他字符打头的单词,然后对于通过了isalpha()测试的单词,使用if或switch语句来确定哪些以元音打头。该程序的运行情况如下:

Enter words (q to quit):

The 12 awesome oxen ambled

quietly across 15 meters of lawn. q

5 words beginning with vowels

4 words beginning consotants

2 others

本题要求用户输入一些单词,由程序判断有哪些由元音字母打头,哪些由辅音字母打头,哪些由其他打头。题目中提示可以使用isalpha()函数来判断是否由字母打头,然后使用if或switch来判断是元音还是辅音,我觉得这种方法还是很不错的,但是要注意输入一定要能够包含并识别空格和回车,并不将这二者作为分隔。

在这里我使用string对象来储存输入的单词,因为string对象可以识别空格和回车作为分隔。而对于判断部分,我们只需要首先对input[0]这第一个字符使用isalpha()函数,然后使用一个if就可以了,判断这第一个字符是不是元音字母,然后连续使用两个else就可以了。另外注意使用“q”来停止输入。

代码如下:

// 6.7.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <cctype>
#include <string>

int main()
{
    using namespace std;
    cout << "Enter words (q to quit):\n";
    int type1 = 0;
    int type2 = 0;
    int type3 = 0;
    string input;
    cin >> input;
    while (input != "q")
    {
	if (isalpha(input[0]))
	{
	    if (input[0] == 'a' || input[0] == 'e' || input[0] == 'i' || input[0] == 'o' || input[0] == 'u')
		type1++;
	    else
		type2++;
	}
	else
	    type3++;
	cin >> input;
    }
    cout << type1 << " words beginning with vowels" << endl;
    cout << type2 << " words beginning with consonants" << endl;
    cout << type3 << " others" << endl;

    system("pause");
    return 0;
}

运行结果如下图所示:



8. 编写一个程序,它打开一个文件,逐个字符地读取该文件,直到到达文件末尾,然后指出该文件中包含多少个字符。

本题要求处理文件,所以必须加入fstream头文件,这个头文件中的ifstream和ofstream是用来打开和输出文件的,其中还有很多函数,在这里我用到了.open()、.is_open()、.good()、.eof()、.close()这几个函数。.open()函数是打开文件,比如.open("6.8.txt")就会打开名为“6.8.txt”的文件了;.is_open()函数时用来判断打开文件是否成功,例如.is_open("6.8.txt"),有可能是该程序的目录下找不到名为“6.8.txt”的文件,那么.is_open()函数就会返回false了;.good()函数是指读取成功;.eof()函数是用来判断是否读取到了最后;.close()函数是用来关闭打开的文件。这里我写的程序是请求用户输入文件名,这样该程序就可以用来打开任意文件,只要在该程序的目录下存在该文件就可以。

代码如下:

// 6.8.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <fstream>
int main()
{
    using namespace std;
    char filename[30];
    ifstream inFile;
    cout << "Enter the name of data file: ";
    cin.getline(filename, 30);
    inFile.open(filename);
    if (!inFile.is_open())
    {
	cout << "Could not open the file" << filename << endl;
	exit(EXIT_FAILURE);
    }
    int count = 0;
    char str;
    inFile >> str;
    while (inFile.good())
    {
	count++;
	inFile >> str;
    }
    if (inFile.eof())
	cout << "End of file reached.\n";
    inFile.close();
    cout << "The total number of characters is " << count << endl;
    system("pause");
    return 0;
}

在这里我在程序的目录下提前创建了一个名为“6.8.txt”的文本文件,如下所示:


运行结果如下图所示:



9. 完成编程练习6,但从文件中读取所需的信息。该文件的第一项应为捐款人数,余下的内容应为成对的行。在每一对中,第一行为捐款人姓名,第二行为捐款数额。即该文件类似于下面:

4

Sam Stone

2000

Freida Flass

100500

Tammy Tubbs

5000

Rich Raptor

55000

本题是对第六题的拓展,拓展的要求就是用户一次性输入所有的内容,第一行为捐款人数,后面每两行就是一个捐款姓名+捐款数额的组合,一次性输入完之后,保存为一个文件,程序去读取该文件,再按第六题的要求输出这些信息。

我们只需要在第六题的基础上进行修改就好,首先,关于内容判断的一律不需要修改完全照搬就可以了;关于文件名,还使用第八题一样的由用户自己输入;在读取文件的时候,对于第一行特殊处理,使用.getline()函数来一次性读取一行,由于是数字所以长度定为1;接下来再去动态分配结构数组,使用循环来读取接下来的内容,每两行读取一次,循环次数即为之前输入的捐款人数,具体的读取方法都是.getline()函数;之后的输出方法与第六题完全相同。

代码如下:

// 6.9.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>  
#include <string>  
#include <fstream>
using namespace std;

struct donation 
{
    char name[30];
    double money;
};

int main() 
{
    ifstream inFile;
    cout << "Please enter the name of your file: ";
    char filename[30];
    cin.getline(filename, 30);
    inFile.open(filename);

    int num;
    inFile >> num;
    char str[30];
    inFile.getline(str, 1);
    donation *d = new donation[num];
    int bigger = 0;

    for (int i = 0; i< num; i++) 
    {
	inFile.getline(d[i].name, 30);
	inFile >> d[i].money;
	inFile.getline(str, 1);
	if (d[i].money>10000) 
	{
	    bigger++;
	}
    }

    if (bigger > 0 && bigger < num) 
    {
	cout << "Grand Patrons" << endl;
	for (int i = 0; i < num; i++) 
	{
	    if (d[i].money>10000) 
	    {
		cout << d[i].name << "\t" << d[i].money << endl;
	    }
	}
	cout << "Patrons" << endl;
	for (int i = 0; i < num; i++)
	{
	    if (d[i].money <= 10000)
	    {
		cout << d[i].name << "\t" << d[i].money << endl;
	    }
	}
    }

    if (bigger == 0) 
    {
        cout << "Grand Patrons" << endl;
	cout << "none" << endl;
	cout << "Patrons" << endl;
	for (int i = 0; i < num; i++)
	{
	    if (d[i].money <= 10000)
	    {
		cout << d[i].name << "\t" << d[i].money << endl;
	    }
	}
    }

    if (bigger == num)
    {
	cout << "Grand Patrons" << endl;
	for (int i = 0; i < num; i++) 
	{
	    if (d[i].money>10000)
	    {
		cout << d[i].name << "\t" << d[i].money << endl;
	    }
	}
	cout << "Patrons" << endl;
	cout << "none" << endl;
    }

    delete[]d;
    inFile.close();
	
    system("pause");
    return 0;
}

然后在程序所在目录下创建一个文本文件,如下所示:


运行结果如下图所示:


猜你喜欢

转载自blog.csdn.net/leowinbow/article/details/80956758
今日推荐