現代において膨大なテキストデータを処理する 技術は不可欠. 基本的な

! 
現代において膨大なテキストデータを処理する
技術は不可欠.
!  就職にも有利.
! 
基本的なテキスト処理の方法を学ぶ.
! 
「cin >> x」や「fin >> x」はホワイトスペースが読み飛
ばされる.
!  ホワイトスペース:スペース,タブ,改行の3つ!
// test.cpp
//実行例
int main(void){
% test
!  基本中の基本だけ.
char ch;
This is a test.
while(cin >> ch) {
Thisisatest.
cout << ch;
}
return 0;
}
スペースが読み飛ばされている!
どうすれば読み飛ばされない?
! 
!  <iomanip>ヘッダファイルをインクルードし,noskipwsを利用.
// test2.cpp
#include<iostream>
#include<iomanip>
using namespace std;
int main(void){
//実行例
! 
// countchar.cpp
% test2
using namespace std;
This is a test.
int main(void){
This is a test.
cout << ch;
//実行例
#include<iostream>
% countchar
This is a test.
(ctlr+d)
int n =0;
12
char ch;
char ch;
while(cin >> noskipws >> ch) {
ホワイトスペースを含めずカウント
while(cin >> ch) { n++; }
cout << n << endl;
スペースが読み飛ばされない!
}
return 0;
}
return 0;
}
! 
ホワイトスペースを含めてカウント
// count2.cpp
#include<iostream>
#include<iomanip>
using namespace std;
int main(void){
int n =0;
! 
何行入力されたかのカウントにもnoskipwsを利用する.
!  利用しないと,改行文字「\n」の判別ができない.
//実行例
% countchar2
// countline.cpp
This is a test.
int main(void){
(ctlr+d)
int n =0;
char ch;
16
while(cin >> noskipws >> ch) {
char ch;
if(ch == \n ){ n++; }
while(cin >> noskipws >> ch) { n++; }
}
cout << n << endl;
cout << n << endl;
return 0;
}
noskipwsを書かないと,改行文
字も読み飛ばされる!
return 0;
}
//実行例
% countline
This
is
a
test
(ctrl+d)
4
! 
入力された文中にいくつ単語があるかを数えたい.
! 
実際にどうカウントする?
!  下の2行の文章が入力された時,どうカウントするか?
!  □:スペース,\n:改行,\t:タブ
! 
H
e
□
i
s
□
a
□
m
a
n
.
I
t
\t
i
s
\t
a
□
p
e
n
.
H
e
□
i
s
□
a
□
m
a
n
.
I
t
\t
i
s
\t
a
□
p
e
n
.
\n
ホワイトスペース(スペース・改行・タブ)を区切りに
して,カウントすればよい.
! 
! 
// countword1.cpp
int main(void){
int n =0;
アルファベッドを読んでいる間は
true.それ以外はfalseとする判
定用の変数.
bool flag = false;
if(ch ==
¦¦ ch == \n ¦¦ ch == \t ){
flag = false;
}else if (flag == false){
flag = true;
n++;
}
cout << n << endl;
return 0;
}
! 
赤の矢印の地点で単語の数を+1する.
青の矢印の地点で単語が終わったことを判定する.
入力された文中にいくつ単語があるかを数えたい.
!  string型を使うと,簡単にカウントできる.
// countword2.cpp
char ch;
while(cin >> noskipws >> ch){
\n
読み込んだ文字がホワイトスペー
スなら,flagをfalseに.
int main(void){
int n = 0;
string str;
while(cin >> str) {
読み込んだ文字がホワイトスペー
スでない,かつ,単語の先頭なら,
単語の数に+1する.
n++;
}
cout << n << endl;
return 0;
}
string型に入力するときは,
ホワイトスペースを区切りに,別
の文字列と判断してくれる.
//実行例
% countword2
This is a test.
Count word!
(ctlr+d)
6
基礎プログラミングでも何度も出てきた.
! 
! 
!  何度やっても出来ていなかった…
!  0 のASCIIコードは0ではないので,注意する.
!  ch- 0 とすれば, 0 - 9 の数字が0-9として扱える.
文字の変換はASCIIコードを利用して行う.
! 
!  ASCIIコードは教科書146ページに掲載.
! 
大文字から小文字,小文字から大文字の変換のために
ASCIIコードを覚える必要はない!
! 
char型chで読み込んだ数字を数字として扱う.
a→c,b→e,…,x→a,y→b,z→cのように,3文字
ずらして変換するには?
!  返還後の文字が小文字のaからそれぞれどれだけ離れているかが
わかればよい.
!  大文字変換(chが小文字): ch = ch ‒ a + A ;
!  ch = ( ch ‒ a +3 )%26 + a
▪  a - a =0, b - a =1,…, z - a =25.
▪  %26がないと,正確に変換されない…なぜ??
▪  A +0= A , A +1= B ,…, A +25= Z .
!  小文字変換(chが大文字): ch = ch ‒ A + a ;
// chconvert.cpp
int main(void){
bool flag = false;
char ch;
while(cin >> noskipws >> ch){
if(ch ==
¦¦ ch == \n ¦¦ ch == \t ){
flag = false;
}else if (flag == false){
アルファベッドを読んでいる間は
true.それ以外はfalseとする判
定用の変数.
読み込んだ文字がホワイトスペー
スなら,flagをfalseに.
! 
!  string型の変数はchar型の配列とみなせることに注意.
// charconvert2.cpp
int main(void){
string str;
while(cin >> str) {
flag = true;
if(str[0] >= a && str[0] <= z ){
if( ch >= a && ch <= z ){
ch = ch ‒ a + A ;
}
}
cout << ch;
str[0] = str[0] ‒ a + A ;
読み込んだ文字が先頭文字かつ,
アルファベットの小文字なら,大
文字に変換.
}
cout << str;
}
}
return 0;
}
1つ前のプログラムをstring型を使って実装する.
return 0;
}
string型に入力するときは,
ホワイトスペースを区切りに,別
の文字列と判断してくれる.
//実行例
% charconvert2
can i help ypu.
Can I Help You.
! 
各行の先頭にスペースが含まれている左のファイルから
スペースを取り除いて,右のファイルを作成したい.
// data.dat
// data1.dat
□□□abc
abc
bcd
bcd
□□□□□cde
cde
□
defg
□□defg
efghi
#include<iostream>
#include<iomanip>
using namespace std;
int main(void){
! 
ホワイトスペースは「cin >> ws;」で明示的に読み飛ば
すことができる.
入力を1行ずつ読み込みたい:getline( )関数を利用.
ファイル冒頭のホワイトスペース
を無視する.
cin >> ws;
char ch;
while(cin >> noskipws >> ch){
cout << ch;
efghi
! 
cin >> ws;
を利用するために<iomanip>ヘッ
ダファイルをインクルードする.
// skipws.cpp
if(ch == \n ) { cin >> ws; }
}
return 0;
}
! 
入力された行数をカウントする.
!  今までは1文字ずつや1単語ずつ読み込んでいた.
getline(cin , line)
キーボードからの入力を1行読み
込んで,lineに保存する.
// countline.cpp
! 
getline(第1引数,第2引数)
!  第1引数:cinやifstreamのオブジェクト(finなど)
int main(void){
string line;
!  第2引数:stringクラスのオブジェクト
int count;
!  getline( cin, str )やgetline( fin, str )など.
while(getline(cin, line)) {
//実行例
count++;
}
cout << #line =
return 0;
}
改行記号を見つけた場合,
次の行の先頭のホワイトスペース
を無視する.
<< count << endl;
% countline
This is a pen.
That is a desk.
It is a notebook.
ctrl+d
#line = 3
! 
getline()関数は,関数が呼ばれた地点から行末までの入
力を読み込む.
int main( ){
getline()関数は,改行以外の文字を区切りにできる.
! 
!  なにも指定していないと,改行記号( \n )ごとに区切る.
実行例
int main( ){
実行例
int x, y;
% ./a.out
string s;
% ./a.out
string s;
32 300 White Chocolate
while(getline(cin, s, , )){
a, b, c, d
while(cin >> x >> y && getline(cin, s)){
9600 White Chocolate
cout << x * y << s << endl;
}
cout << s << endl;
}
b
18060 Orange Cookie
return 0;
c
return 0;
}
d
}
! 
getline(cin , s, 文字)
指定した文字を区切りにして,
sにそこまでの文字列を保存.
find(string)関数は,引数に指定した文字列が,変数
(オブジェクト)が保持する文字列に含まれているかを
判定する.
!  存在する
//findword.cpp
int main( ){
string s;
string line = I will get up early in the morning. ;
(最初の文字列の)先頭からの文字位置を返す.
!  存在しない
! 
a
42 430 Orange Cookie
while(cout << Input a search word :
string::nposという特殊な値を返す.
cout << Found! << endl;
例:string s = I will get up early in the morning.
!  s.find( get )
!  s.find( e )
!  s.find( gets )
&& cin >> s){
if(line.find(s) != string::npos){
}else{
cout << Not Found! << endl;
7が返ってくる.
}
8が返ってくる.
}
string::nposが返ってくる.
return 0;
}
文字列lineに文字列sが,
含まれていれば,Found!
含まれていなければ,Not Found!