(五)《C++ Primer Plus》 | 第 6 章:分支语句和逻辑运算符

  1. 编写一个程序,读取键盘输入,直到遇到 @ 符号为止,并回显输入(数字除外),同时将大写字符转换为小写,小写字符转换为大写。
  • isdigist(char) 判断字符是否为数字, isupper(char) 判断字符是否为大写字母,toupper(char) 将字母转换为大写,islower(char) 判断字符是否为小写字母,tolower(char) 将字母转换为小写。
#include <iostream>

using namespace std;

int main()
{
    // 读取键盘输入的字母
    char ch;
    while (cin >> ch)
    {
        // 遇到 '@' 则停止输入
        if (ch == '@')
        {
            cout << ch << " ";
            break;
        }
        // 遇到数字,不回显
        else if (isdigit(ch))
        {
            continue;
        }
        // 遇到小写字母则将其转换为大写并回显
        else if (islower(ch))
        {
            ch = toupper(ch);
            cout << ch << " ";
        }
        // 遇到大写字母则将其转换为小写并回显
        else if (isupper(ch))
        {
            ch = tolower(ch);
            cout << ch << " ";
        }
        // 其他字母回显
        else 
        {
            cout << ch << " ";
        }
    }
    
    // 换行
    cout << endl;

    return 0;
}
  1. 编写一个程序,最多将 10 个 donation 值读入到一个 double 数组中。程序遇到非数字输入时将结束输入,并报告这些数字的平均值以及数组中有多少个数字大于平均值。
  • cin 输入语句在遇到不匹配的数据类型时返回 false,将其设为循环条件即可判断非数字类型。
#include <iostream>
#include <array>

using namespace std;

int main()
{
    // array 对象 arr,类型为 double,长度为 10
    array<double, 10> arr;
    int i = 0;

    // 循环读取 10 个 double 值
    double v;

    // 统计输入数字的和
    double sum = 0.0;

    // 当输入数据格式和 arr[i] 不匹配时,cin 返回 false 结束循环,从而结束输入
    while (i < 10 && cin >> arr[i])
    {
        sum += arr[i];
        i++;
    }
    
    // 此时 array 长度为 i,计算平均值
    double avg = sum / i;

    // 统计比平均值大的数字个数
    int cnt = 0;
    for (int ii = 0; ii < i; ii++)
    {
        if ((arr[ii] - avg) > 1e-5)
        {
            cnt++;
        }
    }

    cout << "You enter a total of " << i << " numbers, their average is " << avg << 
            ", the number of digits larger than the average is " << cnt << endl;

    return 0;
}
  1. 编写一个菜单驱动程序的雏形。该程序显示一个提供 4 个选项的菜单——每个选项用一个字母标记。如果用户使用有效选项之外的字母进行响应,程序将提示用户输入一个有效的字母,直到用户这样做为止。然后,该程序用一条 switch 语句,根据用户的选择执行一个简单操作。该程序的运行情况如下:
Please enter one of the following choices:
c) carnivore    p) pianist
t) tree         g) game
Please enter a c, p, t, or g: q
Please enter a c, p, t, or g: t
A maple is a tree.
  • 使用 switch 语句判断用户输入类型,如果不是 c,p,t 或 g,则继续循环;否则输出相关信息并中止循环。使用标志变量 flag 来控制是否继续循环,并针对用户输入判断是否更改标志。
#include <iostream>

using namespace std;

int main()
{
    cout << "Please enter one of the following choices: " << endl;
    cout << "c) carnivore       p) pianist" << endl;
    cout << "t) tree            g) game" << endl;

    // 用于退出循环
    int flag = 1;

    cout << "Please enter a c, p, t, or g: ";
    char ch;
    while (flag && cin >> ch)
    {
        switch (ch)
        {
        case 'c':
            cout << "A tiger is a carnivore." << endl;
            flag = 0;
            break;

        case 'p':
            cout << "Beethoven is a pianist." << endl;
            flag = 0;
            break;

        case 't':
            cout << "A maple is a tree." << endl;
            flag = 0;
            break;

        case 'g':
            cout << "Super Mario is a game." << endl;
            flag = 0;
            break;

        default:
            cout << "Please enter a c, p, t, or g: ";
            break;
        }
    }

    return 0;
}
  1. 存在一个包含人物信息的结构体:
struct bop
{
    char fullname[strsize]; // 真实姓名
    char title[strsize];    // 头衔
    char bopname[strsize];  // 秘密姓名
    int preference;         // 偏好
};

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

a. display by name    b. display by tile
c. display by bopname d. display by preference
q. quit

编写程序,根据用户的不同选择来完成不同选项的功能。

  • preference=0 时显示真实姓名,preference=1 时显示头衔,preference=2 时显示秘密姓名。
#include <iostream>

using namespace std;

const int strsize = 20;

struct bop
{
    char fullname[strsize]; // 真实姓名
    char title[strsize];    // 头衔
    char bopname[strsize];  // 秘密姓名
    int preference;         // 偏好
};

// 声明函数,分别完成选项 a、b、c、d 四个功能,int 表示传入数组的大小
void display_by_name(const struct bop*, int);

void display_by_title(const struct bop*, int);

void display_by_bopname(const struct bop*, int);

void display_by_preference(const struct bop*, int);

int main()
{
    // 创建 5 个结构体元素
    const struct bop arr_bop[5] =
    {
        {"Wimp Macho", "P1", "PWimp", 0},
        {"Raki Rhodes", "P2", "PRaki", 1},
        {"Celia Laiter", "P3", "PCelia", 2},
        {"Hoppy Hipman", "P4", "PHoppy", 0},
        {"Pat Hand", "P5", "PPat", 2}
    };

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

    cout << "Enter your choice: ";
    char choice;

    // 退出标志
    int flag = 1;

    // 不断输入,直到输入 'q' 时结束
    while (flag && cin >> choice)
    {
        switch(choice)
        {
        case 'a':
            display_by_name(arr_bop, 5);
            break;
        case 'b':
            display_by_title(arr_bop, 5);
            break;
        case 'c':
            display_by_bopname(arr_bop, 5);
            break;
        case 'd':
            display_by_preference(arr_bop, 5);
            break;
        case 'q':
            cout << "Bye!" << endl;
            flag = 0;
            break;
        }
    }

    return 0;
}

void display_by_name(const struct bop* arr, int n)
{
    for (int i = 0; i < n; i++)
    {
        cout << arr[i].fullname << endl;
    }
}

void display_by_title(const struct bop* arr, int n)
{
    for (int i = 0; i < n; i++)
    {
        cout << arr[i].title << endl;
    }
}

void display_by_bopname(const struct bop* arr, int n)
{
    for (int i = 0; i < n; i++)
    {
        cout << arr[i].bopname << endl;
    }
}

void display_by_preference(const struct bop* arr, int n)
{
    for (int i = 0; i < n; i++)
    {
        // 显示真实姓名
        if (arr[i].preference == 0)
        {
            cout << arr[i].fullname << endl;
        }
        // 显示头衔
        else if (arr[i].preference == 1)
        {
            cout << arr[i].title << endl;
        }
        // 显示秘密姓名
        else if (arr[i].preference == 2)
        {
            cout << arr[i].bopname << endl;
        }
    }
}
  1. 在 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。请编写一个程序,使用循环来要求用户输入收入并报告所得税。当用户输入负数或非数字时,循环将结束。

#include <iostream>

using namespace std;

int main()
{
    // 存放用户输入
    float income;

    cout << "Please input your income (negative and non-numeric will end the input): ";

    // 输入为非数字时退出循环
    while (cin >> income)
    {
        // 统计税额
        float tax = 0.0;

        // 输入为负数时退出循环
        if (income < 0)
        {
            break;
        }

        // 如果收入大于 35000
        if (income > 35000)
        {
            tax = 5000 * 0.0 + 10000 * 0.1 + 20000 * 0.15 + (income - 35000) * 0.2;
        }
        // 收入大于 15000 而小于等于 35000
        else if (income > 15000)
        {
            tax = 5000 * 0.0 + 10000 * 0.1 + (income - 15000) * 0.15;
        }
        // 收入大于 5000 而小于等于 15000
        else if (income > 5000)
        {
            tax = 5000 * 0.0 + (income - 10000) * 0.1;
        }
        // 收入小于 5000
        else 
        {
            tax = 5000 * 0.0;
        }

        cout << "Your income is " << income << ", and your tax is " << tax << endl;
        cout << "Please input your income (negative and non-numeric will end the input): ";
    }

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

using namespace std;

struct patron_info
{
    string name;
    double amount;
};

int main()
{
    cout << "Enter number of patrons: ";
    int num_patrons;
    cin >> num_patrons;

    // 处理 cin 留在队列中的换行符
    cin.get();

    // 结构体数组
    struct patron_info* patrons = new struct patron_info[num_patrons];

    for (int i = 0; i < num_patrons; i++)
    {
        cout << "Enter the name of " << i + 1 << " patron: ";
        getline(cin, patrons[i].name);

        cout << "Enter the amount of " << i + 1 << " patron: ";
        cin >> patrons[i].amount;

        // 处理 cin 留在队列中的换行符
        cin.get();
    }

    // 计数器
    int cnt = 0;

    // 输出重要捐款者
    cout << "Grand Pators: " << endl;
    for (int i = 0; i < num_patrons; i++)
    {
        if (patrons[i].amount > 10000)
        {
            cout << "Patron Name: " << patrons[i].name << endl;
            cout << "Patron Amount: " << patrons[i].amount << endl;
            cnt++;
        }
    }

    // 如果没有重要捐款者,则显示 none
    if (cnt == 0)
    {
        cout << "none" << endl;
    }

    // 计数器清零
    cnt = 0;

    // 输出其他捐款者
    cout << "Patrons: " << endl;
    for (int i = 0; i < num_patrons; i++)
    {
        if (patrons[i].amount <= 10000)
        {
            cout << "Patron Name: " << patrons[i].name << endl;
            cout << "Patron Amount: " << patrons[i].amount << endl;
            cnt++;
        }
    }

    // 如果没有其他捐款者,则显示 none
    if (cnt == 0)
    {
        cout << "none" << endl;
    }

    return 0;
}
  1. 编写一个程序,它每次读取一个单词,直到用户只输入 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 with consonants
2 others 
  • 根据题目提示的方法。
#include <iostream>

using namespace std;

// 检查单词是否以元音打头
bool check(char);

int main()
{
    cout << "Enter words (q to quit): " << endl;
    string word;

    // 记录元音打头单词数量
    int vowels = 0;

    // 记录辅音打头单词数量
    int consonants = 0;

    // 记录第三类单词数量
    int others = 0;

    while (cin >> word)
    {
        // 以非字母打头的单词
        if (!isalpha(word[0]))
        {
            others++;
        }
        // 以字母打头的单词
        else 
        {
            // 遇到 q 退出
            if (word == "q")
            {
                break;
            }

            // 以元音打头的单词
            if (check(word[0]))
            {
                vowels++;
            }
            // 以辅音打头的单词
            else 
            {
                consonants++;
            }
        }
    }
    cout << vowels << " words beginning with vowels." << endl;
    cout << consonants << " words beginning with consonants." << endl;
    cout << others << " others." << endl;

    return 0;
}

bool check(char ch)
{
    return ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u';
}
  1. 编写一个程序,它打开一个文件,逐个字符地读取,直到到达文件末尾,然后指出该文件中包含多少个字符。
  • 基于 ifstream 类的成员函数完成,is_open 函数判断文件是否打开成功,good 函数判断读取字符是否成功,eof 函数判断是否到达文件尾。
#include <iostream>
#include <fstream>

using namespace std;

// 文件名最大长度
const int fnsize = 60;

int main()
{
    // ifstream 对象
    ifstream in_file;

    // 用户手动输入文件名
    cout << "Enter name of data file: ";
    char filename[fnsize];
    cin.getline(filename, fnsize);

    // 打开文件
    in_file.open(filename);

    // 文件打开失败
    if (!in_file.is_open())
    {
        cout << "Could not open the file " << filename << endl;
        exit(EXIT_FAILURE);
    }

    // 从文件读取字符
    char ch;
    in_file >> ch;

    // 统计字符个数
    int count = 0;

    // 读取字符成功且没有到达文件尾
    while (in_file.good())
    {
        count++;
        in_file >> ch;
    }

    // 正常读取完毕,到达文件尾
    if (in_file.eof())
    {
        cout << "End of file reached.\n";
    }
    // 意外退出
    else 
    {
        cout << "Input terminated for unknown reason.\n";
    }

    // 关闭文件
    in_file.close();

    cout << filename << " contains " << count << " characters." << endl;

    return 0;
}
  1. 完成编程练习 6,但从文件中读取所需的信息。该文件的第一项应为捐款人数,余下的内容应为成对的行。在每一对中,第一行为捐款人姓名,第二行为捐款数额。即该文件按类似于下面:
4
Sam Stone
2000
Freida Flass
10050
Tammy Tubbs
5000
Rich Raptor
55000
  • 将题目 6 中的 cin 改为 ifstream 对象即可:
#include <iostream>
#include <fstream>

using namespace std;

struct patron_info
{
    string name;
    double amount;
};

int main()
{
    // ifstream 对象
    ifstream in_file;

    cout << "Enter filename: ";
    string filename;
    getline(cin, filename);

    // 打开文件
    in_file.open(filename);

    // 文件打开失败
    if (!in_file.is_open())
    {
        cout << "Could not open the file " << filename << endl;
        exit(EXIT_FAILURE);
    }

    // 读取捐款人数
    int num_patrons;
    in_file >> num_patrons;
    
    // 处理 cin 留在队列中的换行符
    in_file.get();

    // 结构体数组
    struct patron_info* patrons = new struct patron_info[num_patrons];

    for (int i = 0; i < num_patrons; i++)
    {
        getline(in_file, patrons[i].name);

        in_file >> patrons[i].amount;

        // 处理 cin 留在队列中的换行符
        in_file.get();
    }

    // 计数器
    int cnt = 0;

    // 输出重要捐款者
    cout << "Grand Pators: " << endl;
    for (int i = 0; i < num_patrons; i++)
    {
        if (patrons[i].amount > 10000)
        {
            cout << "Patron Name: " << patrons[i].name << endl;
            cout << "Patron Amount: " << patrons[i].amount << endl;
            cnt++;
        }
    }

    // 如果没有重要捐款者,则显示 none
    if (cnt == 0)
    {
        cout << "none" << endl;
    }

    // 计数器清零
    cnt = 0;

    // 输出其他捐款者
    cout << "Patrons: " << endl;
    for (int i = 0; i < num_patrons; i++)
    {
        if (patrons[i].amount <= 10000)
        {
            cout << "Patron Name: " << patrons[i].name << endl;
            cout << "Patron Amount: " << patrons[i].amount << endl;
            cnt++;
        }
    }

    // 如果没有其他捐款者,则显示 none
    if (cnt == 0)
    {
        cout << "none" << endl;
    }

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值