看着玩着也算是把前六章看完了,前五章的习题都比较简单,对应各章重点的简单应用,第六章就明显比较综合了。在做题的时候期间也出了些自己意想不到的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;
}