文字列

Last-modified: 2013-04-18 (木) 16:16:21
 

今回の目標

文字列について理解し、扱えるようになること。

文字と文字列

C言語では、文字 (1文字) と文字列 (複数文字) は厳密に区別されます。
そのため、両者を同じものと考えて、以下の文章を読むことはやめてください。

また、ここで言う1文字はアルファベットのことを指します *1
日本語はたとえ1文字であっても文字列です。

文字定数と文字列定数

プログラム中に、直接文字や文字列を書く場合には、文字定数文字列定数と呼ばれる形式を使用します。

文字定数は ' (一重引用符、シングルクォーテーション) で囲みます。
文字列定数は " (二重引用符、ダブルクォーテーション) で囲みます。

putchar('A'); // putchar 関数は文字を出力する
putchar('\n'); // 改行
printf("ABC\n");

文字とは何か

私たちはコンピューター上で文字を扱っています。
この文字の実態はただの整数です。

たとえば、アルファベットであれば以下のように定義されます。

このように、文字を整数で定義したものを文字コードといいます。

文字が整数で表されているというのが、信じられないというのであれば、以下のプログラムを実行してみてください。

putchar(65); // A
putchar(66); // B
putchar(67); // C
putchar(10); // \n

ABCと画面に出力されたのではないでしょうか。
このように、文字をコンピューターは数値として認識しているのです。
文字定数で書いたものは、内部的にこのような数値に変換されています。

なお、putchar 関数は printf 関数で代替できます。
整数を文字として表示する場合%cを用います。

以下の例は、上の例と同じです。

printf("%c%c%c%c", 65, 66, 67, 10);

文字の型

文字は、一般的に char 型を用います。
char が character (文字) の略であることから分かる通り、文字を扱うことを目的とした型です。

char 型は次のように使用します。

char a, b, c;

a = 88; // X
b = 'Y';
c = 'Z';

printf("%c%c%c\n", a, b, c); // XYZ

char 型には文字は入りません。

文字列の型

C言語に文字列の型はありません
文字列は文字の配列という形で表します。

たとえば、"ABC"という文字列定数は、以下のような配列として表されています。

string.png

最後の '\0' という文字はヌル文字 *2*3 と言って、文字列の終端を表す特別な文字です。
C言語の文字列には、必ずヌル文字を最後に付けなくてはいけません

上の画像の文字列を格納するには、サイズ 4 の char 型の配列が必要です。
コードで表すと、以下のようになります。

char s[4];

s[0] = 'A';
s[1] = 'B';
s[2] = 'C';
s[3] = '\0';

上のコードは次のようにも書けます。

char s[4] = "ABC";

さらに、宣言時に初期化する場合に限り、配列のサイズを省略できます。

char s[] = "ABC";

このように、宣言時の初期化に限り、上のように文字列定数が代入ができます*4
以下のようにして文字列を代入することはできません

char s[4];

s = "ABC"; // コンパイルエラー

途中で文字列を代入したい場合、別の方法をとる必要があります。

文字の入力

文字を読み込むには、次のようにします。

char a;

scanf("%c", &a);

ただし、上のようにすると空白や改行も文字として読み込んでしまいます。
それを防ぐためには、次のようにします。

char a;

scanf(" %c", &a);

上のように、%c の前に空白を置くと、改行や空白などを読み飛ばせという意味になります。
もちろん、読み飛ばす改行や空白などが無い場合でも、正常に動作します。

printf 関数での文字列の出力

printf 関数で文字列を出力するには、%s を使用します。

char a[] = "ABC";

printf("a = %s\n", a);

文字列の入力

文字列を読み込むには次のようにします。

char s[11];

scanf("%s", s);

文字列を読み込む際には & をつけません
これは間違えやすいので、気をつけてください。

また、配列のサイズは、読み込みたい文字数 + 1 が必要です。
文字列の末尾には、必ずヌル文字を付けなければいけないからです。
上の例では、最大 10 文字まで読み込めます。

scanf で読み込んだ場合、ヌル文字は自動で付けられます。

文字列操作関数

文字列を操作するために、専用の関数が string.h に用意されています。
なお、string とは、文字列のことを指します。

string.h には数多くの関数があるため、すべてをここで紹介することはできません。
代表的なもののみを紹介しますので、詳細は以下のサイトなどをご覧ください。

strcmp 関数

strcmp 関数は文字列を比較する際に使用します。

形式

strcmp(比較したい文字列1, 比較した文字列2);

int result = strcmp(a, b);

if(result == 0){
    printf("%s と %s は等しいです。\n", a, b);
}

else if(result < 0){
    printf("%s のほうが %s より辞書順で先です。\n", a, b);
}

else {
    printf("%s のほうが %s より辞書順で後です。\n", a, b);
}

strcpy 関数

strcpy 関数は、文字列の配列へ文字列をコピーします。

形式

strcpy(コピー先, コピー元);

char s[10];

strcpy(s, "ABC"); // s = "ABC" とはできない

strlen 関数

strlen 関数は、文字列の長さを求めます。

形式

strlen(長さを求めたい文字列);

char s[10];

scanf("%s", s); // & は付けない!!

printf("%s は %d 文字です。\n", s, (int)strlen(s));

課題

課題1

入力された文字をそのまま表示するプログラムを作成しなさい。
ただし、入力される文字は半角英数字とする。

実行例

./a.out
a
a
./a.out
1
1

課題2

入力された文字列をそのまま表示するプログラムを作りなさい。
ただし、文字列は最大 10 文字までとする。

実行例

./a.out
qwerty
qwerty
./a.out
1234567890
1234567890
./a.out
X
X

課題3

文字列が1つ入力されます。
文字列の文字数を出力しなさい。

ただし、文字列は 10 文字以下とします。

実行例

./a.out
abc
3
./a.out
a
1
./a.out
abcdefghij
10

課題4

文字列が2つ入力されます。
辞書順で出力しなさい。

ただし、文字列は 10 文字以下とし、各文字列に空白は含まないものとします。

実行例

./a.out
melon apple
apple melon
./a.out
cherry grape
cherry grape
./a.out
1234567890 0123456789
0123456789 1234567890
./a.out
orange orange
orange orange

挑戦課題

 


*1 厳密には、1 byte (7bit 及び 8 bit) で表現される文字を指します。半角カナ等は、日本語であっても 1 byte で表現できます。
*2 ナル、ニルという場合もあります。
*3 ASCIIでは0番
*4 正確には代入はしてないですが。