学习《C++ Primer Plus》习题篇1 第六版第6章习题

    看着玩着也算是把前六章看完了,前五章的习题都比较简单,对应各章重点的简单应用,第六章就明显比较综合了。在做题的时候期间也出了些自己意想不到的bug,感觉有必要总结一下,记下一些需要注意的点。
1.
注意点:toupper()和tolower()原型是 int toupper(lower)(int )
其实这个时候就可以不用cout<<,而是用cout.put(ch);

int ch = 106;
cout.put(ch);  //output = 'j'!

#include<iostream>
#include<cctype>
int main()
{
    using namespace std;
    cout << "Enter text for special output, and type @ "
        "to terminate input.\n";
    char ch;
    while (cin.get(ch)&&ch!= '@')
    {
        if (isdigit(ch))
            continue;
        else if (islower(ch))
            cout << (char)toupper(ch);
        else if (isupper(ch))
            cout << (char)tolower(ch);
        else
            cout << ch;
    }
    cin.get();
    cin.get();
    return 0;
}

2.
注意点:想要运行程序后保留程序窗口,需要多加几行代来处理非数字输入
//donation.cpp--non-numeric input erminates loop
#include<iostream>
#include<array>
const  int People = 10;
int main()
{
    using namespace std;
    //get data
    array<double, People> donation;
    cout << "Please enter the donation: .\n";
    cout << "You may enter up to " << People << " number<q to terminate>.\n";
    cout << "donation #1: ";
    int i = 0;
    while (i<People&&cin >> donation[i])
    {
        if (++i < People)
            cout << "donation #" << i + 1 << ": ";
    }
    //calculate average
    double total = 0.0;
    for (int j = 0; j < i; j++)
        total += donation[j];
    //report results
    if (i == 0)
        cout << "no donation.\n";
    else
        cout << total / i << " = average money of " << i << " donation.\n";
    cout << "Done.\n";

    if (!cin)  //iput terminated by non-numeric respons
    {
        cin.clear();  //reset input
        cin.get();    //read q
    }
    cin.get();        //read the end of line after last input
    cin.get();        //wait for user to press<Enter>
    return 0;
}

3.
应该还有其他办法,我这个算是个笨方法?
#include<iostream>

int main()
{
    using namespace std;
    cout << "Please enter one of the following choice:\n";
    cout << "c) carnivore\t" << "p) pianist\n"
         << "t) tree     \t" << "g) game\n";
    char ch;
    cin >> ch;
    int back = 0;
    do
    {
        switch (ch)
        {
        case 'c': cout << "A tiger is a carnivore(食肉动物).\n"; back = 0; break;
        case 'p': cout << "Chopin is a famous pianist.\n"; back = 0;  break;
        case 't': cout << "A maple is a tree.\n"; back = 0; break;
        case 'g': cout << "SouthPark's game is very funny.\n"; back = 0;  break;
        default:  back = 1;
                  cout << "Please enter a c, p, t, or g: ";
                  cin >> ch;
        }
    } while (back);
    cin.get();
    cin.get();
    return 0;
}

4.
额...太麻烦了...

5.
#include<iostream>

int main()
{
    using namespace std;
    cout << "Enter the number of tvarps to calculate the tax:\n";
    double tvarps, tax = 0.0;
    while (cin >> tvarps && tvarps >= 0)
    {
        if (tvarps <= 5000)
            tax = 0.0;
        else if (tvarps >= 5001 && tvarps <= 15000)
            tax = (tvarps - 5000)*0.1;
        else if (tvarps >= 15001 && tvarps <= 35000)
            tax = 10000 * 0.1 + (tvarps - 15000)*0.15;
        else
            tax = 10000 * 0.1 + 20000 * 0.15 + (tvarps - 35000 )* 0.2;
        cout << "the tax: " << tax << endl;
    }

    if (!cin)
    {
        cin.clear();
        cin.get();
    }
    cin.get();
    cin.get();
    return 0;

}

6.
注意点:在使用cin.getline(***)和cin.get(***)之前,若是有cin>>输入的话,因为输入的是一个变量+空格,必须在输入你想输入的字符或字符串之前用一个cin.get()把前面cin的换行给接收了!!!!不然你到按逻辑该输入的地方,它自动接收换行符,直接相当把这行代码作废了!!!!!!!!!!!!
#include<iostream>
#include<string>
#include<vector>
using namespace std;

struct donation {
    string name;
    double money;
};

int main()
{
    cout << "Ener the number of donators: ";
    int num;
    cin >> num;
    vector<donation> donator(num);
    cout << "Enter the " << num << " donators name and money: \n";
    //enter the donator' information
    for (int i = 0; i < num; i++)
    {
        cin.get();  //一定一定要注意这个!!!前面有换行的话,换行符留在输入流里
                    //会被getline()和get()给接受了  就直接跳过去你要输入的值了!
        cout << "#" << i + 1 << " " << "name: ";
        getline(cin, donator[i].name);
        cout <<"   "<< "money: ";
        cin >> donator[i].money;
    }
    //show the donators'name in two groups depends on their donation
    cout << "Grand Patrons:\n";
    int j = 0;
    for (int i = 0; i < num; i++)
    {
        if (donator[i].money > 10000)
        {
            cout << donator[i].name << endl;
            j++;
        }
    }
    if (j == 0)
        cout << "none" << endl;
    cout << "Patrons:\n";
    if (j == num)
        cout << "none" << endl;
    else
    {
        for (int i = 0; i < num; i++)
        {
            if (donator[i].money <= 10000)
                cout << donator[i].name << endl;
        }
    }

    cin.get();
    cin.get();
    return 0;
}

7.
注意点:
问题1出在循环的cin>>和cin.get()关于输入空格的用法
cin>>直接忽略空格和回车,这一点要注意了!!!
其实遇到有关单个字符变量,还是直接使用cin.get(ch)和cout.put(ch)很安全!!!
问题2出在循环计数的逻辑
#include<iostream>
#include<cctype>
extern int vowel = 0, consonant = 0, other = 0;
bool isvowel(char ch);
void calculate(char ch);
int main()
{
    using namespace std;
    cout << "Enter words (q to quit):\n";
    char ch;
    
    cin.get(ch);
    calculate(ch);

    while (ch != 'q')
    {
        
        if (ch == ' ' || ch == '\n' || ch == '\t')
        {
            cin.get(ch);
            if(ch!='q')
            calculate(ch);
        }
        else
            cin.get(ch);
            
    }
    cout << vowel << " words beginning with vowels\n"
        << consonant << " words beginning with consonants\n"
        << other << " others.\n";
    cin.get();
    cin.get();
    return 0;
}
//if the alpha is vowel
bool isvowel(char ch)
{
    switch (ch) {
    case 'a':
    case'A':
    case 'e':
    case 'E':
    case 'i':
    case 'I':
    case'o':
    case 'O':
    case 'u':
    case 'U': return true; break;
    default:  return false;
    }

}
void calculate(char ch)
{
    if (isalpha(ch))
    {
        if (isvowel(ch))
            vowel++;
        else
            consonant++;
    }
    else
        other++;
}

8.
注意点:在打开文件时,一定要有判断文件是否打开成功的测试,有时可以加上是因为什么原因读取失败的测试
编写代码思路中不仅仅要注意达成结果的逻辑,要注意“安全”,防止进入不好的状态,这是一个程序猿的基本素养!
//read a file
#include<iostream>
#include<fstream>  //file I/O support
#include<cstdlib>  //support for exit
#include<string>

int main()
{
    using namespace std;
    string filename;
    ifstream inFile;  //object for handling file input
    cout << "Enter name of data file: ";
    getline(cin, filename);
    inFile.open(filename);  //assoxiate inFile with a file
    if (!inFile.is_open())  //fail to open file
    {
        cout << "Could not open the file " << filename << endl;
        cout << "Pragram terminating.\n";
        exit(EXIT_FAILURE);
    }
    char ch;
    int count = 0;

    inFile>>ch;  //get first value
    while (inFile.good())  //while input good and not at EOF
    {
        ++count;
        inFile>>ch;
    }

    if (inFile.eof())
        cout << "End of file reached.\n";
    else if (inFile.fail()) //eof()只能检验EOF,而fail()既可以检验EOF又可以检验
                           //类型不匹配!!!
        cout << "Input terminated by data mismatch.\n";
    else
        cout << "Input terminated for unknow reason.\n";
    if (count == 0)
        cout << "No data processed.\n";
    else
        cout << "The file have " << count << " characters";
    inFile.close();
    cin.get();
    return 0;
}

9.
心得:
    这个程序真拖了很长时间,我最大的心得就是一定要学会自己主动去排错,在中间位置加几行代码看下输出,有些问题调试也看不出来,还有就是对文件流还不是特别熟悉,绕了很大的弯路。我写这个程序一开始在逻辑上是完全没有问题的,唯一错的地方就是没有在while里加一行:inFile.get(),开始还想用cin.get(),哎,要学要练的还有很多呀。
    我为了找到这个错误,测试了文件流输出,当文件里全部都是数字或全部是字符或字符串是,用一个循环来一个个或一行行来读文件是完全没有问题的,但是!但是!一旦数字和字符串混在一起,在读完数字后,它会读数字后面的换行!必须用一个inFile.get()来消这个行,之后才可以读数字后的字符串,真是涨姿势了...
    还有一点,我之前用windows的记事本,没有勾选自动换行选项,所以要自己在最后一行数据加换行符,这一次我用的记事本勾选了自动换行,最后一行是给自动加了换行符的!如果自己再这基础上再加一个换行符是会出错的!这一点也需要注意!
#include<iostream>
#include<string>
#include<vector>//vector类确实使用new和delete来管理内存,但这种工作是自动完成的
#include<fstream>
using namespace std;

struct donation {
    string name;
    double money;
};

int main()
{

    ifstream inFile;
    inFile.open("test.txt");
    if (!inFile.is_open())  //文件没有打开就直接终止程序
    {
        cout << "Could not open the file " << endl;
        cout << "Program terminating.\n";
        exit(EXIT_FAILURE);
    }

    int num;
    inFile >> num;  //inFile 是ifstream类的一个对象,cin可用的操作inFile也可以用!
    vector<donation> donator(num);
    cout << "There are " << num << " donators' information in the file: \n";
    //enter the donator' information
    int i = 0;
    while (inFile.good() && i<num)
    {
        inFile.get();
        getline(inFile, donator[i].name);
        inFile >> donator[i].money;
        i++;
    }
    if (inFile.eof())
        cout << "End of file reached.\n";
    else if (inFile.fail())
        cout << "Input terminated by data mismatch.\n";
    else
        cout << "Input terminated for unknown reasons.\n";

    if (i == 0)
        cout << "No data processed.\n";
    else
    {
        //show the donators'name in two groups depends on their donation
        cout << "Grand Patrons:\n";
        int j = 0;
        for (int i = 0; i < num; i++)
        {
            if (donator[i].money > 10000)
            {
                cout << donator[i].name 
                    << "   " << donator[i].money << endl;
                j++;
            }
        }
        if (j == 0)
            cout << "none" << endl;
        cout << "Patrons:\n";
        if (j == num)
            cout << "none" << endl;
        else
        {
            for (int i = 0; i < num; i++)
            {
                if (donator[i].money <= 10000)
                    cout << donator[i].name
                    <<"   "<<donator[i].money<< endl;
            }
        }
    }
    inFile.close();
    
    cin.get();
    return 0;
}
 

猜你喜欢

转载自blog.csdn.net/ly_222222/article/details/81285695
今日推荐