6.1 if ステートメント
if 構文: if (test-condition) statement
if テスト条件はブール値に強制されるため、0 は false に変換され、ゼロ以外は true に変換されます。
6.2 if-else ステートメント
6.3 if else if else 構造体
if else ステートメント自体はステートメントであるため、else の後に置くことができます。
// ifelseif.cpp -- using if else if else
#include <iostream>
const int Fave = 27;
int main()
{
using namespace std;
int n;
cout << "Enter a number in the range 1-100 to find ";
cout << "my favorite number: ";
do
{
cin >> n;
if (n < Fave)
cout << "Too low -- guess again: ";
else if (n > Fave)
cout << "Too high -- guess again: ";
else
cout << Fave << " is right!\n";
} while (n != Fave);
return 0;
}
6.4 論理演算子: &&、||、および !
6.4.1 論理和演算子: ||
- 論理 || は関係演算子より優先順位が低くなります。
- 元の式の一部またはすべてが true (またはゼロ以外) の場合、結果の式は true と評価され、それ以外の場合、式は false と評価されます。
- まず左側の値を変更してから、右側の値を判断します。(
i++ < 6||i== j
i の元々の値が 10 だったと仮定すると、i と j を比較すると、i の値は 11 になります。) - 左側の式が true の場合、C++ は右側の式を判断しません。これは、1 つの式が true である限り、論理式全体が true であるためです。
6.4.2 論理 AND 演算子: &&
- 論理 && は関係演算子より優先順位が低くなります。
- 論理 AND 演算子は、論理 OR 演算子よりも優先されます。
- 結果の式は、元の式が両方とも true の場合にのみ true と評価されます。
- 左側が false の場合、論理式全体が false である必要があり、その場合、C++ は右側を判断しなくなります。
- && 演算子を使用すると、それぞれが特定の範囲の値に対応する一連の if else if else ステートメントを作成することもできます。
6.4.3 論理 NOT 演算子: !
- ! 演算子は、それに続く式の真理値を否定します。
- ! 演算子は、すべての関係演算子および算術演算子よりも優先されます。
// (将!运算符用于函数返回值)来筛选可 赋给int变量的数字输入。
#include <iostream>
#include <climits> // 注意这里要加上头文件,定义了符号常量(INT_MAX和INT_MIN)
bool in_num(double n);
int main(void)
{
using namespace std;
cout << "Enter a number:";
double num; // 注意这里要定义成 double 类型的输入,取值范围比int大
cin >> num;
while (!in_num(num))
{
cout << "Enter against:";
cin >> num;
}
int value = (int) num;
cout << "you have entered the integer " << value << endl;
return 0;
}
bool in_num(double n)
{
if (n <= INT_MAX && n >= INT_MIN)
return true;
else
return false;
}
外
Enter a number:6234128679
Enter against:135
you have entered the integer 135
6.5 cctype 文字ライブラリ
- これにより、文字が大文字、数字、句読点などであるかどうかを判断するなどのタスクが簡素化されます。これらの関数のプロトタイプは、ヘッダー ファイル cctype (旧形式では ctype.h) で定義されます。
- たとえば、この関数はch が文字の場合は
isalpha(ch)
ゼロ以外の値を返し、それ以外の場合は 0 を返します。 - 同様に、 ch がカンマやピリオドなどの句読点文字である場合、この関数
ispunct(ch)
は true を返します。 - これらの関数の戻り値の型は bool ではなく int です。
AND および OR を使用して、文字 ch がアルファベット文字のコードであるかどうかをテストします。if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))
isalpha( ) を使用して、文字 ch がアルファベット文字のコードであるかどうかをテストします。if (isalpha(ch))
一部の ctype ライブラリ関数
- isalnum() この関数は、引数が英数字、つまり文字または数字の場合に true を返します。
- isalpha() は引数が文字の場合に true を返します
- isblank() は、引数が空白または水平タブの場合に true を返します。
- iscntrl() は、引数が制御文字の場合に true を返します。
- isdigital() パラメータが数値 (0 ~ 9) の場合、関数は true を返します。
- isgraph() は、引数がスペース以外の印刷文字の場合に true を返します。
- is lower() この関数は、引数が小文字の場合に true を返します。
- isprint() は、引数が印刷文字 (スペースを含む) の場合に true を返します。
- ispunct() は、引数が句読点の場合に true を返します。
- isspace() は、引数がスペース、フィード、ラインフィード、キャリッジリターン、水平タブ、垂直タブなどの標準の空白文字である場合に true を返します。
- isupper() この関数は、引数が大文字の場合に true を返します。
- isxdigital() パラメータが 16 進数、つまり 0 ~ 9、f 、A F の場合、この関数は true を返します。
- to lower() は、引数が大文字の場合は小文字を返し、それ以外の場合は引数を返します。
- toupper() は、引数が小文字の場合は大文字を返し、そうでない場合は引数を返します。
// 使用isalpha( )来检 查字符是否为字母字符,
// 使用isdigits( )来测试字符是否为数字字符,如 3,
// 使用isspace( )来测试字符是否为空白,如换行符、空格和制表符,
// 使用ispunct( )来测试字符是否为标点符号。
// 该程序还复习了if else if结 构,并在一个while循环中使用了cin.get(char)。
#include <iostream>
#include <cctype>
int main(void)
{
using namespace std;
cout << "Enter text for analysis, and type @ to terminate input.\n";
char ch;
int whitespace = 0, digits = 0, chars = 0, punct = 0, others = 0;
cin.get(ch);
while (ch != '@')
{
if (isalpha(ch))
chars++;
else if (isspace(ch))
whitespace++;
else if (isdigit(ch))
digits++;
else if (ispunct(ch))
punct++;
else
others++;
cin.get(ch);
}
cout << chars << " letters, " << whitespace << " whitespace, " << digits << " digits, "
<< punct << " punctuations, " << others << " others.\n" << endl;
return 0;
}
6.6 条件演算子: ? :
構文: expression1 ? expression2 : expression3
if else ステートメントの置換に使用される演算子は、C++ で 3 つのオペランドを必要とする唯一の演算子です。
式 1 が true の場合、条件式全体が式 2 の値に評価され、それ以外の場合、式全体が式 3 の値に評価されます。
// 条件运算符生成一个表达式,因此是一个值,可以将其赋给变量或将其放到一个更大的表达式中
#include <iostream>
int main(void)
{
using namespace std;
int a, b;
cout << "Enter two int:";
cin >> a >> b;
int c = a>b ? a : b; // 条件运算符生成一个表达式,因此是一个值,可以将其赋给变量或将其放到一个更大的表达式中
cout << "c = " << c << endl;
return 0;
}
6.7 switch ステートメント
switch ステートメントの形式:
switch (integer-expression) {
case label1 : statement(s)
case label2 : statement(s)
...
default : statement(s)
}
- switch ステートメントが実行されると、プログラムは integer-expression の値でマークされた行にジャンプします。たとえば、integer-expression の値が 4 の場合、プログラムは case 4: というラベルの行を実行します。
- 名前が示すように、integer-expression は整数値をもたらす式である必要があります。さらに、各ラベルは整数定数式である必要があります。最も一般的なラベルは int または char 定数 (1 や 'q' など) ですが、列挙子である場合もあります。switch ステートメントは、int 値を列挙子のラベルと比較するときに、列挙子を int に昇格します。
- integer-expression がどのラベルにも一致しない場合、プログラムは「default」というラベルの行にスキップします。Default ラベルはオプションです。これが省略され、一致するラベルがない場合、プログラムはスイッチ後のステートメントにジャンプします。
- プログラムがスイッチ内の特定のコード行にジャンプした後は、特別な命令がない限り、後続のすべてのステートメントが順番に実行されます。プログラムは次のケースに到達しても自動的に停止しません。特定のステートメントのセットを実行した後にプログラムを停止するには、break ステートメントを使用する必要があります。これにより、プログラムはスイッチの後のステートメントにジャンプします。
// 如何使用switch和break来让用户选择简单菜单。
// 该程序使用showmenu( )函数显示一组选项,然后使用switch语句, 根据用户的反应执行相应的操作。
// 使用字符(而不是整数)作为菜单选项和switch标签,则可以为大写标签和小写标签提供相同的语句
#include <iostream>
using namespace std;
void showmenu();
void report();
void comfort();
int main(void)
{
showmenu();
int choice;
cin >> choice;
while(choice != 5) // 当用户输入了5时,while循环结束。输入1到4将执行switch列表中 相应的操作,输入6将执行默认语句。
{
switch(choice)
{
case 1 : cout << "\a\n"; break;
case 2 : report(); break;
case 3 : cout << "The boss was in all day.\n"; break;
case 4 : comfort(); break;
default : cout << "That's not a choice.\n";
}
showmenu();
cin >> choice;
}
cout << "Bye!\n";
return 0;
}
void showmenu()
{
cout << "Please enter 1, 2, 3, 4, or 5 :\n"
"1) alarm 2) report\n"
"3) alibi 4) comfort 5) quit\n";
}
void report()
{
cout << "I LOVE YOU!\n";
}
void comfort()
{
cout << "THINK YOU!\n";
}
6.8 continue ステートメントと Break ステートメント
- Break ステートメントと continue ステートメントの両方で、プログラムはコードのセクションをスキップできます。
- Break ステートメントを switch ステートメントまたは任意のループ内で使用すると、プログラムが switch またはループの後のステートメントにジャンプします。
- continue ステートメントはループ内で使用され、プログラムがループ本体内の残りのコードをスキップして新しいループを開始できるようにします。
// 该程序让用户输入 一行文本。循环将回显每个字符,如果该字符为句点,则使用break结束循环。
// 这表明,可以在某种条件为true时,使用break来结束循环。
// 接下来,程序计算空格数,但不计算其他字符。当字符不为空格时,循环使用continue语句跳过计数部分。
#include <iostream>
#include <cstring>
const int ArSize = 80;
int main(void)
{
using namespace std;
cout << "Please enter string str:";
char str[ArSize];
cin.get(str, ArSize).get();
cout << "Complete line:\n" << str << endl;
int space = 0;
for (int i=0; i < strlen(str); i++)
{
cout << str[i];
if (str[i] == ' ')
{
space++;
continue; // 虽然continue语句导致该程序跳过循环体的剩余部分,但不会跳过循环的更新表达式
}
if (str[i] == '.')
break;
}
cout << endl << space << " space\n";
cout << "Done!";
return 0;
}
C++ には goto ステートメントもあります。
// 下面的语句将跳到使用paris:作为标签的位置:
char ch;
cin >> ch;
if (ch == 'P')
goto paris;
cout << ...
...
paris: cout << "You've just arrived at Paris.\n";
6.9 ループして数値を読み取る
タイプミスと EOF の両方により、cin は false を返します。clear() メソッドは不正な入力フラグをリセットし、ファイルの終わりもリセットします。
この式はcin>>fish[i]
実際には cin メソッドへの関数呼び出しであり、cin を返します。cin がテスト状態の場合は bool 型に変換されます。変換された値は、入力が成功した場合は true、それ以外の場合は false です。
ユーザーが何か間違った内容を入力したことをプログラムが検出すると、次の 3 つのステップを実行する必要があります。
- 新しい入力を受け入れるために cin をリセットします。
- 間違ったエントリを削除します。
- ユーザーに追加の入力を求めます。
// 假设程序要求用户提供5个高尔夫得分,以计算平均成绩。如果用户输入非数字输入,程序将拒绝,并要求用户继续输入数字。
// 可以看到,可以使用cin输入表达式的值来检测输入是不是数字。
// cingolf.cpp -- non-numeric input skipped
#include <iostream>
const int Max = 5;
int main()
{
using namespace std;
// get data
int golf[Max];
cout << "Please enter your golf scores.\n";
cout << "You must enter " << Max << " rounds.\n";
int i = 0;
for (i = 0; i < Max; i++)
{
cout << "round #" << i+1 << ": ";
while (!(cin >> golf[i])) // 使用cin输入表达式的值来检测输入是不是数字。
{
cin.clear(); // reset input
while (cin.get() != '\n')
continue; // get rid of bad input
cout << "Please enter an int number:";
}
}
// calculate average
double total = 0.0;
for (i = 0; i < Max; i++)
total += golf[i];
// report results
cout << total / Max << " = average score " << Max << " rounds\n";
return 0;
}
外:
Please enter your golf scores.
You must enter 5 rounds.
round #1:20
round #2:dk
Please enter an int number:30
round #3:10
round #4:50
round #5:60
34 = average score 5 rounds
6.10 基本的なファイル I/O
#include // ostream->cout istream->cin
#include // ofstream ifstream
#include // exit() のサポート
6.10.1 cin入力
- ヘッダー ファイル iostream を含める必要があります。
- ヘッダー ファイル iostream は、入力を処理するための istream クラスを定義します。
- ヘッダー ファイル iostream は、cin という名前の istream 変数 (オブジェクト) を宣言します。
- 名前空間 std を指定する必要があります。たとえば、要素 cin を参照するには、プラグマ using または接頭辞 std:: を使用する必要があります。
- cin を演算子 >> と組み合わせて使用すると、さまざまなタイプのデータを読み取ることができます。cin メソッドと get( ) メソッドを使用して文字を読み取ることができ、cin メソッドと getline( ) を使用して文字行を読み取ることができます。
- cin を eof( ) および failed( ) メソッドと組み合わせて使用すると、入力が成功したかどうかを判断できます。
- オブジェクト cin 自体がテスト条件として使用される場合、最後の読み取り操作が成功した場合はブール値 true に変換され、それ以外の場合は false に変換されます。
- 入力に cin を使用する場合、プログラムは入力を一連のバイトとして認識し、各バイトが文字エンコーディングとして解釈されます。ターゲットのデータ型に関係なく、入力は文字データ (テキスト データ) として開始されます。cin オブジェクトは、テキストを他のタイプに変換します。
38.5 19.2 // 输入,输入一开始为文本
char ch;
cin >> ch; // 3 输入行中的第一个字符被赋给ch
int n;
cin >> n; // 38 直到遇到非数字字符
double x;
cin >> x; // 38.5 直到遇到第一个不属于浮点数的 字符
char word[50];
cin >> word; // 38.5 直到遇到空白字符,cin将这4个字符的字符编码存储到数组word中,并在末尾加上一个空字符。
char word[50];
cin.geline(word,50); // 直到遇到换行符,并在末尾加上一个空字符。换行符被丢弃,输入队列中的下一个字符是下一行中的第一个字符。
int number;
cin >> number; // 写入一个数字
char ch;
cin >> ch; // 输入一个字符,不保留空格和换行符
string str, str1[2];
getline(cin, str); // 写入一个string
getline(cin, str1[1]); // 写入一个string数组中的一个string变量
char ch[100];
(cin >> ch).get(); //以空白(空格、 制表符和换行符)来确定字符串的结束位置。保留换行符;把回车键生成的换行符留在了输入队列中。
cin.getline(ch, 100); //每次读取一行字符串输入,丢弃换行符;arraySize(包括结尾字符)。
cin.get(ch, 100).get(); //每次读取一行字符串输入,保留换行符;
char ch;
cin.get(ch);
... // 然后进行一系列操作
cin.get(); // 消除空行
6.10.2 cout出力
- ヘッダー ファイル iostream を含める必要があります。
- ヘッダー ファイル iostream は、出力を処理するための ostream クラスを定義します。
- ヘッダー ファイル iostream は、cout という名前の ostream 変数 (オブジェクト) を宣言します。
- 名前空間 std を指定する必要があります。たとえば、要素 cout および endl を参照するには、プラグマ using または接頭辞 std:: を使用する必要があります。
- cout を演算子 << と組み合わせて使用すると、さまざまな種類のデータを表示できます。
6.10.3 ファイル出力・ファイルへの書き込み
- ヘッダー ファイル fstream を含める必要があります。
- ヘッダー ファイル fstream は、出力を処理するための ofstream クラスを定義します。
- 通常の命名規則に従っていることを条件として、1 つ以上の ofstream 変数 (オブジェクト) を宣言し、好きな方法で名前を付ける必要があります。
- 名前空間 std を指定する必要があります。たとえば、stream 要素を参照するには、プラグマ using または接頭辞 std:: を使用する必要があります。
- ofstream オブジェクトをファイルに関連付ける必要があります。これを行う方法の 1 つは、open() メソッドを使用することです。
- ファイルの使用が終了したら、メソッド close( ) を使用してファイルを閉じる必要があります。
- ofstream オブジェクトを演算子 << と組み合わせて使用すると、さまざまなタイプのデータを出力できます。
ファイル出力の主な手順は次のとおりです。
// 1、包含头文件fstream
#include <iostream> // ostream->cout istream->cin
#include <fstream> // ofstream ifstream
// 2、声明自己的ofstream对象,为其命名
ofstream outFile; // outFile an ofstream object
ofstream fout; // fout an ofstream object
// 3、将这种对象与特定的文件关联起来:
outFile.open("fish.txt"); // outFile used to write to the fish.txt file
// 打开已有的文件,以接受输出时,默认将它其长度截短为零,因此原来的内容将丢失。
char filename[50];
cin >> filename; // user specifies a name
fout.open(filename); // fout used to read specified file
// 4、使用cout那样使用该ofstream对象:
double wt = 125.8;
outFile << wt; // write a number to fish.txt
char line[81] = "Objects are closer than they appear.";
fout << line << endl; // write a line of text
// 5、使用close()关闭文件:
outFile.close(); // done with file
fout.close(); // 方法close( )不需要使用文件名作为参数,这是因为outFile已经同特定的文件关联起来。
// 如果您忘记关闭文件,程序正常终止时将自动关闭它。
// 文件输出
#include <iostream> // ostream->cout istream->cin
#include <fstream> // ofstream ifstream
int main(void)
{
using namespace std;
char automoblie[50];
int year;
double a_price, d_price;
ofstream outFile; // 2、创建对象
outFile.open("carinfo.txt"); // 3、关联文件,创建文件
cout << "Enter the make and model of automobile:";
cin.getline(automoblie, 50);
cout << "Enter the model year:";
cin >> year;
cout << "Enter the origional asking price:";
cin >> a_price;
d_price = 0.913 * a_price;
cout << fixed; // 不要以科学计数法显示
cout.precision(2); // 显示输出精度到小数点后两位
cout.setf(ios_base::showpoint); // 即使小数点后面为零也显示出来
cout << "Make and model:" << automoblie << endl; // 屏幕输出是使用cout的结果
cout << "Year: " << year << endl;
cout << "Was asking $" << a_price << endl;
cout << "Now asking $" << d_price << endl;
outFile << fixed;
outFile.precision(2);
outFile.setf(ios_base::showpoint);
outFile << "Make and model: " << automoblie << endl; // 和 cout 使用方法一样,在文本输出
outFile << "Year: " << year << endl; // outFile将cout显示到屏幕上的内容写入到了文件 carinfo.txt中
outFile << "Was asking $" << a_price << endl;
outFile << "Now asking $" << d_price << endl;
outFile.close(); // 方法close( )不需要使用文件名作为参数,这是因为outFile已经同特定的文件关联起来。
// 如果您忘记关闭文件,程序正常终止时将自动关闭它。
return 0;
}
外:
6.10.4 ファイル入力・ファイル読み込み
- ヘッダー ファイル fstream を含める必要があります。
- ヘッダー ファイル fstream は、入力を処理するための ifstream クラスを定義します。
- 通常の命名規則に従っている限り、1 つ以上の ifstream 変数 (オブジェクト) を宣言し、好きな名前を付ける必要があります。
- 名前空間 std を指定する必要があります。たとえば、要素 ifstream を参照するには、プラグマ using または接頭辞 std:: を使用する必要があります。
- ifstream オブジェクトはファイルに関連付ける必要があります。これを行う 1 つの方法は、open() メソッドを使用することです。
- ファイルの使用が終了したら、close() メソッドを使用してファイルを閉じる必要があります。
- ifstream オブジェクトと演算子 >> を組み合わせて使用すると、さまざまなタイプのデータを読み取ることができます。
- ifstream オブジェクトと get( ) メソッドを使用して文字を読み取ることができ、ifstream オブジェクトと getline( ) を使用して文字行を読み取ることができます。
- ifstream を eof( )、fail( ) などのメソッドと組み合わせて使用すると、入力が成功したかどうかを判断できます。
- ifstream オブジェクト自体がテスト条件として使用される場合、最後の読み取り操作が成功した場合はブール値 true に変換され、それ以外の場合は false に変換されます。
ファイル入力の主な手順:
// 1、包含头文件fstream
#include <iostream> // ostream->cout istream->cin
#include <fstream> // ofstream ifstream
#include <cstdlib> // support for exit()
// 2、声明ifstream对象,为其命名
ifstream inFile; // inFile an ifstream object
ifstream fin; // fin an ifstream object
// 3、将ifstream对象与特定的文件关联起来
inFile.open("bowling.txt"); // inFile used to read bowling.txt file
char filename[50];
cin.getline(filename, 50);
fin.open(filename); // fin used to read specified file
// 方法2-1:string filename;
// 方法2-2:getline(cin, filename);
// 4、检查文件是否被成功打开的首先方法是使用方法is_open( )
inFile.open("bowling.txt");
if (!inFile.is_open())
{
exit(EXIT_FAILURE);
}
// 如果文件被成功地打开,方法is_open( )将返回true;因此如果文件 没有被打开,表达式!inFile.isopen( )将为true。
// 函数exit( )的原型是在头 文件cstdlib中定义的,在该头文件中,还定义了一个用于同操作系统通 信的参数值EXIT_FAILURE。函数exit( )终止程序。
// 5、使用cin那样使用ifstream对象
double wt;
inFile >> wt; // read a number from bowling.txt
char line[81];
fin.getline(line, 81); // read a line of text
// 6、使用close()关闭文件:
inFile.close();
ファイルが正常に開かれたかどうかを確認します: is_open( )
存在しないファイルを入力のために開こうとするとどうなりますか? この種のエラーは、後で ifstream オブジェクトを入力に使用するときに失敗の原因になります。
ファイルが正常に開かれたかどうかを確認する最初の方法は、 is_open( ) メソッドを使用することです。
- ファイルが正常に開かれた場合、メソッド is_open( ) は true を返します。したがって、ファイルが開かれなかった場合、式 !inFile.isopen( ) は true になります。
- 関数exit()のプロトタイプはヘッダファイルcstdlibに定義されており、このヘッダファイルにはオペレーティングシステムと通信するためのパラメータ値EXIT_FAILUREも定義されている。関数 exit( ) はプログラムを終了します。
inFile.open("bowling.txt");
if (!inFile.is_open())
{
exit(EXIT_FAILURE);
}
ファイルにエラーがないか確認してください
- まず、プログラムはファイルを読み取るときに EOF を超えてはなりません。最後にデータを読み取ったときに EOF が発生した場合、メソッド eof( ) は true を返します。
- メソッド failed( ) は、最後の読み取り操作中に型の不一致が発生した場合に true を返します (EOF が発生した場合にも true を返します)。
- ファイルが破損している場合、またはハードウェアに障害がある場合、bad() は true を返します。
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 reason.\n";
- Good( ) メソッド。エラーが発生しなかった場合は true を返します。
while (inFile.good()) // while input good and not at EOF
{
...
}
// 表达式inFile >> value的 结果为inFile,而在需要一个bool值的情况下,inFile的结果为 inFile.good( ),即true或false。
inFile >> value; // get first value
while (inFile.good()) // while input good and not at EOF
{
// loop body goes here
inFile >> value; // get next value
}
// 将两条输入语句用一条用作循环测试的输入语句代替。
// 要计算表达 式inFile >> value的值,程序必须首先试图将一个数字读取到value中。
while (inFile >> value) // read and test for success
{
// loop body goes here
// omit end-of-loop input
}
// 打开用户指定的文件,读取其中的数字,然后指出文件中包含多少个值以及它们的和与平均值。
// 首先必须创建一个包含数字的文本文件。
// sumafile.cpp -- functions with an array argument
#include <iostream>
#include <fstream> // file I/O support
#include <cstdlib> // support for exit()
const int SIZE = 100;
int main()
{
using namespace std;
char filename[SIZE];
ifstream inFile; // object for handling file input
cout << "Enter name of data file:";
cin.getline(filename, SIZE); // 通常,除非在输入的文件名中包含路径,否则程序将在可执行文件所属的文件夹中查找。
inFile.open(filename); // associate inFile with a file
if (!inFile.is_open()) // failed to open file
{
cout << "Could not open the file " << filename << endl;
cout << "Program terminating.\n";
exit(EXIT_FAILURE);
}
double value;
double sum = 0.0;
int count = 0; // number of items read
inFile >> value; // get first value
while (inFile.good()) // while input good and not at EOF
{
++count; // one more item read
sum += value; // calculate running total
inFile >> value; // get next value
}
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 reason.\n";
if (count == 0)
cout << "No data processed.\n";
else
{
cout << "Items read: " << count << endl;
cout << "Sum: " << sum << endl;
cout << "Average: " << sum / count << endl;
}
inFile.close(); // finished with the file
return 0;
}
外:
6.11 概要
- C++ には、オプションを管理するための if ステートメント、if else ステートメント、switch ステートメントが用意されています。if ステートメントを使用すると、プログラムはステートメントまたはステートメントのブロックを条件付きで実行します。つまり、プログラムは、特定の条件が満たされた場合に特定のステートメントまたはステートメントのブロックを実行します。if else ステートメント プログラムは、2 つのステートメントまたはステートメントのブロックのうち 1 つを実行することを選択します。このステートメントに if else を追加して、さまざまなオプションを提供できます。switch ステートメントは、一連のオプションの 1 つを実行するようにプログラムに指示します。
- C++ には、意思決定を支援する演算子も用意されています。第 5 章では、2 つの値を比較する関係式について説明します。If および if else ステートメントは通常、テスト条件として関係式を使用します。論理演算子 (&&、||、および !) を使用すると、関係式を結合または変更して、より詳細なテストを作成できます。条件演算子 (?:) は、2 つの値のうち 1 つを選択するコンパクトな方法を提供します。
- cctype 文字ライブラリは、文字入力を分析するための便利で強力なツールのセットを提供します。
- ループと選択ステートメントはファイル I/O に便利なツールであり、ファイル I/O はコンソール I/O に非常に似ています。ifstream オブジェクトと ofstream オブジェクトを宣言し、それらをファイルに関連付けると、それらを cin や cout と同様に使用できるようになります。
- ループと決定ステートメントを使用すると、興味深く、インテリジェントで強力なプログラムを作成できます。
6.12 復習用の質問
5. C++ では、!!x は x と同じですか?
不確かな。たとえば、x=10 の場合、!x=0、!!x=1 となります。ただし、x がブール変数の場合、!!x は x です。
8. 数値を使用する場合と比較して、メニュー オプションやケース ラベルを表す文字 (a や c など) を使用する利点は何ですか?
整数ラベルが使用されており、ユーザーが整数以外の数値 (q など) を入力すると、整数入力では文字を処理できないため、プログラムがハングします。ただし、文字ラベルが使用されており、ユーザーが 5 などの整数を入力した場合、文字入力では 5 が文字として扱われます。次に、switch ステートメントのデフォルト部分で、別の文字の入力を求めるプロンプトが表示されます。
6.13 プログラミング演習
// 2
// 编写一个程序,最多将10个donation值读入到一个double数组中(如果您愿意,也可使用模板类array)。
// 程序遇到非数字输入时将结束输入,并报告这些数字的平均值以及数组中有多少个数字大于平均值。
#include <iostream>
#include <array>
const int ArSize = 10;
int main(void)
{
using namespace std;
array<double, ArSize> donation;
double sum = 0.0, average = 0.0;
int count = 0, bigger = 0;
cout << "Please enter the double numerial:";
// ***判断值读入到一个double数组中***
while ((cin >> donation[count])
{
if (++count == ArSize)
break;
cout << "Please enter the double numerial:";
}
for (int i=0; i < count; i++)
sum += donation[i];
average = sum/count;
for (int i=0; i < count; i++)
if (donation[i] > average)
bigger++;
cout << average << " number's average." << endl;
cout << bigger << " numbers are bigger than average." << endl;
return 0;
}
// 3
// 编写一个菜单驱动程序的雏形。该程序显示一个提供4个选项的菜单——每个选项用一个字母标记。
// 如果用户使用有效选项之外的字母 进行响应,程序将提示用户输入一个有效的字母,直到用户这样做为止。
// 然后,该程序使用一条switch语句,根据用户的选择执行一个简单操作。
#include <iostream>
using namespace std;
void menu(void);
int main(void)
{
menu();
char ch;
cin.get(ch);
while (ch != 'c' && ch != 'p' && ch != 't' && ch != 'g')
{
cin.get();
cout << "Please enter c, p, t or g :";
cin.get(ch);
}
switch (ch)
{
case 'c' : cout << "cccccccc\n";break;
case 'p' : cout << "pppppppp\n";break;
case 't' : cout << "tttttttt\n";break;
case 'g' : cout << "gggggggg\n";break;
}
return 0;
}
void menu(void)
{
cout << "Please enter one of the following choices:\n"
"c) carnivore \tp) pianist\n"
"t) tree \tg) game\n";
}
// 4
// 加入Benevolent Order of Programmer后,在BOP大会上,人们便可以通过加入者的真实姓名、头衔或秘密BOP姓名来了解他(她)。
// 请编写一个程序,可以使用真实姓名、头衔、秘密姓名或成员偏好来列出成员。编写该程序时,请使用下面的结构:
#include <iostream>
void menu(void);
void display(char ch);
using namespace std;
const int strsize = 40;
const int usersize = 5;
// Benevolent Order of Programmers 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
};
bop user[usersize] =
{
{
"Wimp Macho", "AA", "AAA", 0},
{
"Raki Rhodes", "BB", "BBB", 1},
{
"Celia Laiter", "CC", "CCC", 2},
{
"Hoppy Hipman", "DD", "DDD", 0},
{
"Pat Hand", "EE", "EEE", 1}
};
int main(void)
{
menu();
char input;
cin.get(input);
while (input != 'q')
{
display(input);
cin.get(); // 消耗回车
cin.get(input);
}
cout << "Bye!" << endl;
return 0;
}
void menu(void)
{
cout << "a. display by name \tb. display by title\n"
"c. display by bopname \td. display by preference\n"
"q. quit\n";
}
void display(char ch)
{
switch (ch)
{
case 'a' :
for (int i=0; i<usersize; i++)
cout << user[i].fullname << endl;
break;
case 'b' :
for (int i=0; i<usersize; i++)
cout << user[i].title << endl;
break;
case 'c' :
for (int i=0; i<usersize; i++)
cout << user[i].bopname << endl;
break;
case 'd' :
for (int i=0; i<usersize; i++)
{
if (user[i].preference==0)
cout << user[i].fullname << endl;
else if (user[i].preference==1)
cout << user[i].title << endl;
else if (user[i].preference==2)
cout << user[i].bopname << endl;
}
break;
default :
if (ch == 'a' || ch == 'b' || ch == 'c' || ch == 'd')
cout << "Next choice:";
else
cout << "Please enter character a, b, c, d or q :";
}
}
// 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(void)
{
float tvarps, tax;
cout << "Please enter tvarps:";
while ((cin >> tvarps) && (tvarps >= 0))
{
if (tvarps <= 5000)
tax = 0;
else if (tvarps > 5000 && tvarps <= 15000)
tax = (tvarps-5000) * 0.1;
else if (tvarps > 15000 && tvarps <= 35000)
tax = 10000 * 0.10 + (tvarps-15000) * 0.15;
else
tax = 10000 * 0.10 + 20000 * 0.15 + (tvarps-35000) * 0.2;
cout << tax << endl;
cout << tvarps-tax << endl;
}
return 0;
}
// 6
// 编写一个程序,记录捐助给“维护合法权利团体”的资金。
// 该程序要求用户输入捐献者数目,然后要求用户输入每一个捐献者的姓名和款项。
// 这些信息被储存在一个动态分配的结构数组中。每个结构有两个成员:用来储存姓名的字符数组(或string对象)和用来存储款项的 double成员。
// 读取所有的数据后,程序将显示所有捐款超过10000的捐款者的姓名及其捐款数额。该列表前应包含一个标题,指出下面的捐款者是重要捐款人(Grand Patrons)。
// 然后,程序将列出其他的捐款者,该列表要以Patrons开头。
// 如果某种类别没有捐款者,则程序将打印单词“none”。该程序只显示这两种类别,而不进行排序。
#include <iostream>
#include <cstring>
using namespace std;
const int namesize = 20;
struct donation
{
string name;
double money;
};
int main(void)
{
int number = 0;
cout << "Please enter number:";
cin >> number;
cin.get();
donation *ps = new donation[namesize];
for (int i=0; i < number; i++)
{
cout << "donor #" << i+1 << ": \n";
cout << "Enter name :";
getline(cin, ps[i].name);
cout << "Enter money :";
cin >> ps[i].money;
cin.get();
}
bool empty = true;
cout << "Grand Patrons :" << endl;
for (int i=0; i < number; i++)
{
if (ps[i].money > 10000)
{
cout << ps[i].name << "\t" << ps[i].money << endl;
empty = false;
}
}
if (empty == true)
cout << "None.\n";
empty = true;
cout << "Patrons :" << endl;
for (int i=0; i < number; i++)
{
if (ps[i].money <= 10000)
{
cout << ps[i].name << "\t" << ps[i].money << endl;
empty = false;
}
}
if (empty == true)
cout << "None.\n";
delete [] ps;
return 0;
}
// 7
// 编写一个程序,它每次读取一个单词,直到用户只输入q。
// 然后,该程序指出有多少个单词以元音打头,有多少个单词以辅音打头,还有多少个单词不属于这两类。
// 为此,方法之一是,使用isalpha( )来区分以字母和其他字符打头的单词,
// 然后对于通过了isalpha( )测试的单词,使用if或switch语句来确定哪些以元音打头。
#include <iostream>
#include <cctype>
#include <cstring>
int main(void)
{
using namespace std;
int vowels = 0, consonants = 0, others = 0;
string words;
cout << "Enter words (q to quit):";
while ((cin >> words) && (words != "q")) // string 用双引号
{
if (isalpha(words[0]))
{
switch (words[0]) // char 用单引号
{
case 'a' : case 'e' : case 'i' : case 'o' : case 'u' :
case 'A' : case 'E' : case 'I' : case 'O' : case 'U' : vowels++;
default : consonants++;
}
}
else
others++;
}
cout << vowels << " words beginning with vowels" << endl;
cout << consonants << " words beginning with consonants\n";
cout << others << " others\n";
return 0;
}
// 8
// 编写一个程序,它打开一个文件文件,逐个字符地读取该文件,直到到达文件末尾,然后指出该文件中包含多少个字符。
#include <iostream> // ostream->cout istream->cin
#include <fstream> // ofstream ifstream
#include <cstdlib> // support for exit()
int main(void)
{
using namespace std;
char ch;
int count;
char filename[50];
ifstream inFile; // inFile an ifstream object
cout << "Please enter the file name:";
cin.getline(filename, 50); // user specifies a name
inFile.open(filename); // inFile used to read specified file
if (!inFile.is_open()) // 检查文件是否被成功打开的首先方法是使用方法is_open( )
{
cout << "Filed to open the file." << endl;
exit(EXIT_FAILURE);
}
while (!inFile.eof())
{
inFile >> ch;
count++;
}
cout << filename << " havs " << count << " characters." << endl;
inFile.close();
return 0;
}
// 完成编程练习6,但从文件中读取所需的信息。该文件的第一项 应为捐款人数,余下的内容应为成对的行。
// 在每一对中,第一行为捐款 人姓名,第二行为捐款数额。即该文件类似于下面:
#include <fstream>
#include <iostream>
#include <cstring>
#include <cstdlib> // support for exit()
using namespace std;
const int namesize = 20;
struct donation
{
string name;
double money;
};
int main(void)
{
ifstream inFile;
char filename[50];
cout << "Please enter the file name:";
cin.getline(filename, 50); // user specifies a name
inFile.open(filename); // inFile used to read specified file
if (!inFile.is_open()) // 检查文件是否被成功打开的首先方法是使用方法is_open( )
{
cout << "Filed to open the file." << endl;
exit(EXIT_FAILURE);
}
int number = 0;
inFile >> number;
if (number <= 0)
exit(EXIT_FAILURE);
cout << "number:" << number << endl;
inFile.get();
donation *ps = new donation[namesize];
int i = 0;
while ((!inFile.eof()) && (i < number))
{
cout << "donor #" << i+1 << ": \n";
getline(inFile, ps[i].name);
cout << "Read name:" << ps[i].name << endl;
inFile >> ps[i].money;
cout << "Read money:" << ps[i].money << endl;
i++;
inFile.get(); // 再读取一次然后,判断是否到文件末尾
}
bool empty = true;
cout << "Grand Patrons :" << endl;
for (int i=0; i < number; i++)
{
if (ps[i].money > 10000)
{
cout << ps[i].name << "\t" << ps[i].money << endl;
empty = false;
}
}
if (empty == true)
cout << "None.\n";
empty = true;
cout << "Patrons :" << endl;
for (int i=0; i < number; i++)
{
if (ps[i].money <= 10000)
{
cout << ps[i].name << "\t" << ps[i].money << endl;
empty = false;
}
}
if (empty == true)
cout << "None.\n";
delete [] ps;
return 0;
}