ここでは、 ある特定の文字列を読み取るまで、 標準入力から文字を読み取り、処理を続けるプログラムについて考えます。
ある文字列とある文字列を比較し、一致しているかどうかを確かめるには、 string.h
ライブラリの strcmp
関数を使います。
ある文字列1
と 文字列2
を比較する場合、 strcmp
関数は以下のような形で使います。
if(strcmp(文字列1, 文字列2) == 0){ /* 比較した文字列が一致した場合の処理 */ } else { /* 比較した文字列が一致しなかった場合の処理 */ }
もし文字列同士が一致する場合、 strcmp
関数は 0 を返し、一致しない場合0でない値 を返します。
たとえば、以下は END
と言う文字が現れるまで標準入力から文章を読み取り、その後の処理を行うプログラムです。
#include<stdio.h> #include<string.h> int main(){ char text[100]; char end[4] = "END"; while(1){ scanf("%s", text); if(strcmp(text, end) == 0){ break; } printf("[%s]\n", text); } return 0; }
ここで、scanfで文字列を読み取る際に、読み込んだ文字列を保存するための引数に &
がついていないことに注意してください。
ITP1_A でも学んだ通り、 scanf
関数の引数には変数に保持されている値ではなく メモリの場所を指定 します。
配列の名前は配列の先頭のメモリを示すので、ここでは scanf
関数の引数には配列名である text
を指定しています。
つまり、以下に示す二つの scanf
関数は同じ処理を行います。
scanf("%s", text);
scanf("%s", &text[0]);
scanf
関数は空白・改行までを読み取ることができるので、単語を一つ一つ読み込み、それぞれに対して文字列操作・比較を行うことが出来ます。
以下のプログラムでは、入力された空白を含む文字列(100文字以下)に対して、空白区切りで分割し、標準出力を行います。
#include<stdio.h> #include<string.h> int main(){ char input[100]; // 一回目の単語読み取り scanf("%s", input); printf("%s\n", input); // 二回目以降の単語読み取り、ENDが現れるまで読み取り続ける while(1){ scanf("%s", input); if(strcmp(input, "END") == 0) { break; } printf("%s\n", input); } return 0; }
strcmp
関数を使う上で注意しなければならないのが、大文字小文字の区別です。
strcmp
関数は文字コードで文字列同士の比較を行っているため、 Computer
と computer
は一致していない扱いになります。
そこで、比較をする前に、まず読み込んだ文字列を全て小文字に変換する必要があります。 以下のプログラムは、標準入力で与えられた一つの文字列(50文字以下)を全て小文字にするプログラムです。
#include<stdio.h> #include<ctype.h> #include<string.h> int main(){ char input[50]; int i; scanf("%s", input); for(i = 0; input[i] != '\0'; i++){ input[i] = tolower(input[i]); } printf("%s\n", input); return 0; }
このプログラムに以下のような標準入力を与えると、
Aizu-University-Online-Judge
以下のように標準出力されます。
aizu-university-online-judge
オンラインジャッジではじめるC/C++プログラミング入門 (マイナビ)AIZU ONLINE JUDGE のコース問題を題材にした解説書です。各トピックごとに C/C++ 言語の基礎的な内容を学習し、Introduction to Programming の演習問題にチャレンジしていきます。内容は敷居の高いものではなく、プログラミング初学者が取り組む例題からスタートしています。 |