このドキュメントは http://edu.net.c.dendai.ac.jp/ 上で公開されています。
#include <stdio.h>
main(){
char x[]="abc";
char y[]="def";
char z[50];
/* 文字列をつなげる処理 */
printf("文字列 %s と %s をつなげると %s になる\n",x,y,z);
}
C 言語には文字列型という変数はありません。 従って、「文字列型変数へ文字列を代入」という操作はできません。 あるのは、文字型だけなので、一文字一文字コピーしていくしかありません。 まず、問題を簡単にするために、文字配列 z[] に x[] をコピーしていくこと を考えましょう。 これは、 x[0] を z[0] に、 x[1] を z[1] にと、文字列が終るまで('\0' が見 つかるまで)繰り返せば良いので、次のように書けます。
int i;
for(i=0;x[i]!='\0';i++){
z[i]=x[i];
}
但しこの手法だと、 '\0' を検出するとコピーを止めますので(図1)、 '\0' 自体はコピーされません。 従って、z[] の最後の文字は '\0' で終ってません。 但し、コピーが終った後、 x[i] は '\0' を示しています。そして z[i] は x[i] をコピーし終った直後を示してます。 そこで、z[i] に y[0] を、z[i+1] に y[1] をと y[] が終るまでコピーすれ ば、これで x[] と y[] をつなげることになります(図2)。 別の変数 j を用意すれば、z[i+j] に y[j] をコピーすれば良いので、次のよ うに書けます(j は宣言済みとします)。
for(j=0;y[j]!='\0';j++){
z[i+j]=y[j];
}
そして、z[] の最後に '\0' を入れます。 これらをまとめると、文字列の結合ができます。
#include <stdio.h>
main(){
char x[]="abc";
char y[]="def";
char z[50];
int i,j;
for(i=0;x[i]!='\0';i++){
z[i]=x[i];
}
for(j=0;y[j]!='\0';j++){
z[i+j]=y[j];
}
z[i+j]='\0';
printf("文字列 %s と %s をつなげると %s になる\n",x,y,z);
}
なお、 z[i+j] の代わりに z[i] とし、 j と一緒に i を増やしていっても良 い。
C 言語では全ての文や式に値を持ちます。 例えば代入文は代入した数を値に持ちます。 j=0 という代入文の値は 0 です。 従って次のような記法が可能です(代入文は右から処理されます)。
i=j=0
この場合、「j=0」 により j に 0 が代入されますが、「j=0」の式の値は 0 なので、 i にはこの式の値 0 が代入されます。
条件文の式の値は、真であれば 1、偽であれば 0 です。従って、 0==0 は 1、1==0 は 0 の値を持ちます。一方、条件文では、 0 なら偽、0 以 外の値なら真だと判定します。したがって、次の文は同じ意味を持ちます。
if(x!=0){} if(x){}
MS-DOS プロンプトやコマンドプロンプトでは、キーボードを押すと字が入力 され、画面に字が表示されます。 しかし、このキーボードや画面の関係を変えることが可能です。 例えば、プログラムの実行結果をファイルに残したり、プログラムにキーボー ドからではなくファイルの内容を入力したりできます。 コンピュータの入出力は基本的にはキーボードと画面が対応していますが、特 定のファイルに変更が可能になっています(この入出力の変更のことをリ ダイレクトと言います)。
標準出力を変更するにはコマンドを入力した後、「> 出力ファイル名」 を付け足します。 例えば、ディレクトリの内容をファイルに保存するには次のようにします。
dir > file1
このようにするとディレクトリの内容は画面に表示されず、 file1 に保存さ
れます。
echo abc > file2
標準入力を変更するにはコマンドを入力した後、「< 入力ファイル名」を つけます。 例を説明する前に、次のファイルを作って下さい。ファイル名は file3 にして下さい。
3 1 2
このファイルを sort コマンドに入力するには次のようにします。
sort < file3すると、画面に与えた数が小さい順に出力されます。
sort コマンドはファイルの内容を小さい順に並べるコマンドです。 ファイルの最後に一番小さい値が来たら、その値を先頭に表示する必要がある ため、 sort の処理はファイルを全て読み終えてからでないと実行できません。 sort に限らず、ファイルを処理するプログラムはファイルの終りを知る必要 があります。 そのため、 OS はファイルが終ると EOF記号(End of File)という特殊な記号 (番兵)をプログラムに与えます。これにより、プログラムは ファイルが終ったことを知ることができます。 MS-DOS や Windows では Ctrl-Z という記号になります。 例えば、次のようにすると、 sort コマンドはキーボードから入力した数字を 並べ替えます。
例 sort[Enter] 3[Enter] 1[Enter] 2[Enter] [Ctrl-Z][Enter]
コマンドの出力をファイルに「追加」したい時は >> を使用 します。
例 echo abc > file1 echo def >> file1
コマンドの出力を、他のコマンドの入力にしたい時は |(縦棒) を使用しま す。このように複数のコマンドをつなげて処理することをパイプ処理 と言います。
例 dir | sort dir | more dir | sort | more
C 言語で標準入力から一文字得るには getchar() 関数を使います。 この関数を使用すると、入力された文字が文字型の値として得ることができま す。 つまり c=getchar(); とすると、一文字得ることができます。 ファイルの終りに達すると EOF という値になります。
ファイルの終りまで一文字ずつ読みながら処理をするには、一文字読む毎に EOF かどうか判定する必要があります。 つまり、プログラムは「(A)一文字読み、読んだ文字が EOF でないとき→(B) 読んだ文字を処理をする」ということ繰り返すことになります。 つまり概念的には次のようなプログラムになります。
while(一文字読み、読み込んだ文字が EOF でないとき){ 読んだ文字を処理する }
while 文の条件は式の値を利用すると次のように書けます。
while((c=getchar())!=EOF){ 読み込んだ文字の入っている変数 c に対する処理 }
次は標準入力を標準出力にただ書き写すプログラムです。
#include <stdio.h> main(){ char c; while((c=getchar())!=EOF){ printf("%c",c); } }
なお、 MS-DOS プロンプトはキーボードから EOF(Ctrl-Z) を受けとると次の 出力文が無効になるというバグがあります。 入力を受けとり終ってから何か出力する際は、空の行を打つ printf 文が必要 になります。但し、コマンドプロンプトでは大丈夫です。
次の操作で変数 i,j の値はどうなっているか?
#include <stdio.h> main(){ printf("Hello World!\n"); }なお、 gcc Developer Station 2000 でコンパイルすると、プロジェクトファ イルのあるディレクトリに Debug というディレクトリが出来、その中に実行 可能な exe ファイルが作られます。
次のプログラムを完成させ、ファイルの文字数を数えるようにしなさい。
また、このプログラムが何文字あるか、このプログラムの標準入力に与えて調
べなさい(つまり 「
#include <stdio.h> main(){ char c; int n=0; while((c=getchar())!=EOF){ /* 一文字受けとったら、 n を一増やす */ } printf("\n"); /* MS-DOS プロンプトのバグ対策 */ printf("合計 %d 文字\n",n); }
変数 x に文字を与えておき、その文字がファイル中に何文字現れたかを数え るプログラムを書きなさい。
入力ファイルに対して、一行が長い場合、 10 文字ずつ折り返すプログラムを 作りなさい。