応用プログラミング 第 5 回 テキスト入力処理 2017 年 10 月 18 日 ( 水 )
第 7 章 テキスト入力処理
1 文字ずつの処理 (P.58) char 型などに入力する cin >> x や fin >> x はホワイトスペースが読み飛ばされる仕様 ホワイトスペース : スペース ( 空白 ), Tab( タブ ), 改行 // sample.cpp char ch; while(cin >> ch) cout << ch; // 実行例 This is a test. Thisisatest. スペースが読み飛ばされている
1 文字ずつの処理 (P.58) どうすれば飛ばされないようになる? <iomanip> ヘッダに入っている noskipws を使用 // sample2.cpp #include<iostream> #include<iomanip> using namespace std; char ch; // 実行例 This is a test. This is a test. スペースが読み飛ばされない! while(cin >> noskipws >>ch) cout << ch;
ホワイトスペースの明示的な読み飛ばし (P.62) 左のテキストファイルを右のように作成し直したい 全てのホワイトスペースを飛ばしてしまうと, 改行などもされなくなってしまう // sample.txt abc xyz ABC XYZ // result.txt abc xyz ABC XYZ cin >> ws を用いて行頭の空白だけ読み飛ばす!
ホワイトスペースの明示的な読み飛ばし (P.62) // sample3.cpp #include<iostream> #include<iomanip> using namespace std; cin >> ws; char ch; while(cin >> noskipws >> ch){ cout << ch; if(ch == n ) cin >> ws;
入力文字のカウント (P.59) ホワイトスペースを含めずにカウント // count1.cpp #include<iostream> using namespace std; int n = 0; char ch; while(cin >> ch){ n++; cout << n << endl; // 実行例 This is a test. (ctrl+d) 12
入力文字のカウント (P.59) ホワイトスペースを含めてカウント // count2.cpp #include<iostream> #include<iomanip> using namespace std; int n = 0; char ch; while(cin >> noskipws >> ch){ n++; cout << n << endl; // 実行例 This is a test. (ctrl+d) 16
入力行のカウント (P.59) 何行入力されたのかのカウントにも noskipws を用いる // count2.cpp #include<iostream> #include<iomanip> using namespace std; int n = 0; char ch; while(cin >> noskipws >> ch){ if(ch == n ) n++; cout << n << endl; // 実行例 This is first. Second. Third. Fourth. (ctrl+d) 4
単語のカウント (P.60) これまでは文字数を数えていた T h i s _ i s _ a _ 1 2 文中に含まれる単語数を数えたい T h i s _ i s _ a _ 1 2 * どうすれば単語ごとにカウントできる?
単語のカウント (P.60) ホワイトスペースで区切って考えればよい! T h i s _ i s _ a _ : カウント +1( 単語の開始 ) : 区切り ( 単語の終り ) 単語が始まってから, ホワイトスペースまでを 1 単語としてカウントしていく
単語のカウント (P.60) 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;
string 型による単語のカウント (P.60) string 型変数は, WS を区切りとして, 別の文字列と判断してくれる int n = 0; string str; while(cin >> str){ n++; cout << n << endl; // 実行例 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) char ch; while(cin >> noskipws >> ch){ if( a <= ch && ch <= z ){ ch = ch a + A ; // 小文字 大文字 cout << ch; // 実行例 This is a test. Change words. (ctrl+d) THIS IS A TEST. CHANGE WORDS.
string 型による文字変換 (P.63) // 各単語の先頭を大文字にする string str; while(cin >> str){ if( a <= str[0] && str[0] <= z ){ str[0] = str[0] a + A ; cout << str; string 型に文を入力するときは, WS を区切りに別の文字列として判断してくれる // 実行例 can i help you? (ctrl+d) Can I Help You?
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 行読み込み, 第 2 引数で設定した変数に格納する
1 行ずつの処理 :getline()(p.64) // 入力された行数をカウントするプログラム string line; int count = 0; while(getline(cin, line)){ count++; cout << #line = << count << endl; // 実行例 This is a test. That is a cat. It is a post. (ctrl+d) #line = 3 *getline() は何も指定しなければ, 改行記号 n ごとに区切る
区切り文字ごとの処理 (P.65) * 改行記号 n 以外で区切るように指定することもできる string s; while(getline(cin, s,, )){ cout << s << endl; // 実行例 Cat, dog, rabbit and cow (ctrl+d) Cat dog rabbit and cow getline(cin, s, 文字 ) 指定した文字を区切りにして, s にそこまでの文字列を保存.
行の途中から行末までの入力 (P.65) *getline() 関数は関数が呼ばれた地点から区切りまでの 入力を 1 行として読み込む int a; string s; while(cin >> a && getline(cin, s)){ cout << s << endl; // 実行例 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 を返す s.find( them ) string::npos が返ってくる
部分文字列の検出 :find()(p.66) 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;
練習問題 問題. a~z が適当な順で何行か並んでいるファイル (data.txt) の中で指定したアルファベットの小文字が各行の何文字目にあるかを全て出力するプログラムを作成せよ. ただし, 各行には 26 種類すべての小文字アルファベットが現れており, また各行内では重複はないものとする. // data.txt の中身 abcdefghijklmnopqrstuvwxyz nopqbcdefghaijklmrwxyzstuv zyxwvutsrqponmlkjihgfedcba vutsrqnmlkzwjicbayxpohgfed // 実行例検索文字 : a 1 行目 1 文字目 2 行目 12 文字目 3 行目 26 文字目 4 行目 17 文字目