応用プログラミング
第5回
テキスト入力処理
2017年10月18日(水)
1文字ずつの処理(P.58)
• char型などに入力する「cin >> x」や「fin >> x」は ホワイトスペースが読み飛ばされる仕様 ➢ ホワイトスペース: スペース(空白), Tab(タブ), 改行 // sample.cpp int main(){ char ch; while(cin >> ch) cout << ch; return 0; } // 実行例 This is a test. ↲ Thisisatest. スペースが読み飛ばされている1文字ずつの処理(P.58)
• どうすれば飛ばされないようになる? ➢ <iomanip>ヘッダに入っている noskipws を使用 // sample2.cpp #include<iostream> #include<iomanip> using namespace std; int main(){ char ch; while(cin >> noskipws >>ch) cout << ch; return 0; } // 実行例 This is a test. ↲ This is a test. スペースが読み飛ばされない!ホワイトスペースの明示的な読み飛ばし(P.62)
• 左のテキストファイルを右のように作成し直したい ➢ 全てのホワイトスペースを飛ばしてしまうと, 改行なども されなくなってしまう… 「cin >> ws」を用いて行頭の空白だけ読み飛ばす! // sample.txt abc xyz ABC XYZ // result.txt abc xyz ABC XYZホワイトスペースの明示的な読み飛ばし(P.62)
// sample3.cpp #include<iostream> #include<iomanip> using namespace std; int main(){ cin >> ws; char ch; while(cin >> noskipws >> ch){ cout << ch; if(ch == ‘¥n’) cin >> ws; } return 0; }入力文字のカウント(P.59)
• ホワイトスペースを含めずにカウント // count1.cpp #include<iostream> using namespace std; int main(){ int n = 0; char ch; while(cin >> ch){ n++; } cout << n << endl; return 0; } // 実行例 This is a test. ↲ (ctrl+d) 12入力文字のカウント(P.59)
• ホワイトスペースを含めてカウント // count2.cpp #include<iostream> #include<iomanip> using namespace std; int main(){ int n = 0; char ch; while(cin >> noskipws >> ch){ n++; } cout << n << endl; return 0; } // 実行例 This is a test. ↲ (ctrl+d) 16入力行のカウント(P.59)
• 何行入力されたのかのカウントにもnoskipwsを用いる // count2.cpp #include<iostream> #include<iomanip> using namespace std; int main(){ int n = 0; char ch; while(cin >> noskipws >> ch){ if(ch == ‘¥n’) n++; } cout << n << endl; return 0; } // 実行例 This is first. ↲ Second. ↲ Third. ↲ Fourth. ↲ (ctrl+d) 4単語のカウント(P.60)
• これまでは文字数を数えていた T h i s _ i s _ a _ • 文中に含まれる単語数を数えたい 1 T h i s _ i s _ a _ 1 2 2 *どうすれば単語ごとにカウントできる…?単語のカウント(P.60)
• ホワイトスペースで区切って考えればよい! T h i s _ i s _ a _ :カウント+1(単語の開始) :区切り(単語の終り) • 単語が始まってから, ホワイトスペースまでを 1単語としてカウントしていく単語のカウント(P.60)
int main(){int n = 0, char ch, bool flag = false; while(cin >> noskipws >> ch){ if(ch == ‘ ’ || ch == ‘¥n’ || ch == ‘¥t’){ flag = false; }else if(!flag){ flag = true; n++; } } cout << n << endl; return 0; }
string型による単語のカウント(P.60)
• string型変数は, WSを区切りとして, 別の文字列と判断してくれる int main(){ int n = 0; string str; while(cin >> str){ n++; } cout << n << endl; return 0; } // 実行例 This is a test. ↲ Count words. ↲ (ctrl+d) 6文字の変換(P.61)
• 文字の変換はASCIIコードを用いて行う ➢ 各文字のASCIIコードを覚える必要はない! • 様々な文字変換 ➢ 大文字 → 小文字: ch = ch – ‘A’ + ‘a’ ➢ 小文字 → 大文字: ch = ch – ‘a’ + ‘A’ ➢ char型で読み込んだ数字文字を数値として扱う > ch – ‘0’ とすれば, ‘0’-‘9’の数字が0-9として扱える ➢ 3文字ずらし変換(a → d, b → e, …, y → b, z → c) > ch = (ch – ‘a’ + 3) % 26 + ‘a’文字の変換(P.61)
int main(){ char ch; while(cin >> noskipws >> ch){ if(‘a’ <= ch && ch <= ‘z’){ ch = ch – ‘a’ + ‘A’; // 小文字 → 大文字 } cout << ch; } return 0; } // 実行例 This is a test. ↲ Change words. ↲ (ctrl+d) THIS IS A TEST. CHANGE WORDS.string型による文字変換(P.63)
// 各単語の先頭を大文字にする int main(){ string str; while(cin >> str){ if(‘a’ <= str[0] && str[0] <= ‘z’){ str[0] = str[0] – ‘a’ + ‘A’; } cout << str; } return 0; } string型に文を入力するときは, WSを区切りに別の文字列として判断してくれる // 実行例can i help you? ↲ (ctrl+d)
1行ずつの処理:getline()(P.64)
• これまで, 文が入力されると1文字 or 1単語ずつ読み込んでいた ➢ 入力を一行ずつ読み込む方法として, getline()関数を用いるgetline(第1引数, 第2引数)
• 第1引数:cin, ifstreamのオブジェクト(fin等) • 第2引数:string型の変数(正確には, stringクラスのオブジェクト) (例) getline(cin, str), getline(fin, str), etc…*つまり, getline()関数の引数は入力とstring型変数の組
1行ずつの処理:getline()(P.64)
// 入力された行数をカウントするプログラムint main(){ string line; int count = 0;
while(getline(cin, line)){ count++;
}
cout << “#line = ” << count << endl; return 0; } // 実行例 This is a test. ↲ That is a cat. ↲ It is a post. ↲ (ctrl+d) #line = 3 *getline()は何も指定しなければ, 改行記号‘¥n’ごとに区切る
区切り文字ごとの処理(P.65)
int main(){ string s; while(getline(cin, s, ‘,’)){ cout << s << endl; } return 0; } *改行記号‘¥n’以外で区切るように指定することもできる // 実行例Cat, dog, rabbit and cow ↲ (ctrl+d)
Cat dog
rabbit and cow
getline(cin, s, 文字)
指定した文字を区切りにして, sにそこまでの文字列を保存.
行の途中から行末までの入力(P.65)
*getline()関数は関数が呼ばれた地点から区切りまでの 入力を1行として読み込む int main(){ int a; string s;while(cin >> a && getline(cin, s)){ cout << s << endl; } return 0; } // 実行例 20 chocolates ↲ 300 handles ↲ (ctrl+d) chocolates handles
部分文字列の検出:find()(P.66)
find(string)
*引数に指定した文字列が変数(オブジェクト)が保持する 文字列に含まれているのかどうかを判定する ➢ 存在する → (最初の文字列の)先頭からの文字位置を返す ➢ 存在しない → string::npos という特殊な値を返す*例:string s = “I will get up early in the morning.” ➢ s.find(“get”) → 7 を返す
➢ s.find(“I”) → 0 を返す ➢ s.find(‘e’) → 8 を返す
部分文字列の検出:find()(P.66)
int main(){string s;
string line = “I have two cars.”;
while(cout << “Input a search word.” && cin >> s){ if(line.find(s) != string::npos)
cout << “Found!” << endl; else
cout << “Not Found!” << endl; }
return 0; }