Another introduction to programming language C 0A: 文字列

文字列型はC言語にはない.文字列はcharの配列として扱う.charは1文字を表すのに適当と考えられている型で,必ず1バイトの大きさ(ただし1バイトが何ビットかは処理系に依存する)を持つデータである.

C言語には可変長の配列が無い.配列は,別途配列の長さを記録しておかないといけない.これでは,文字列の場合あまりにも不便であるので,文字列に関しては特殊なルールがある.すなわち,文字列はその終端に終端を表す記号(ターミネータ・シンボル)をつけることで,配列の終わりを示すのである.例えば,いまappleという文字列を配列sに格納したいとしよう.

char s[6] = { 'a', 'p', 'p', 'l', 'e', '\0' };

が文字列の定義方法である.'a' はaを表す文字コードに置き換えられる.ここに '\0' がターミネータ・シンボルである.ターミネータ・シンボルは整数の0と等価なので,

char s[6] = { 'a', 'p', 'p', 'l', 'e', 0 };

としてもよい.もっと簡単な書き方がある.次のコードはこれまでのコードと同じ意味である.

char s[6] = "apple";

ターミネータ・シンボルは自動的に付加される.配列のサイズはコンパイル時に自動的に決められるので,コードは以下のように縮められる.

char s[] = "apple";

普通,配列はそのサイズをどこかに保存しておくものである.文字列の場合は,サイズが必要になる場面は限られていること,変数が二つ(文字配列を表すポインタとそのサイズを表す整数)になると面倒なこと,ターミナル・シンボルで終わる文字列は長さを調べることができることから,サイズを別途保存しておくことは普通しない.次の関数strlenは文字列の長さを調べる.

#include <string.h>

void func(void) {
  char s[] = "apple";
  int length = strlen(s);
  ...
}

文字列をコピーしたいときはこうする.

#include <string.h>

void func(void) {
  char s[] = "apple";
  char *d = calloc(6, sizeof(char));
  strcpy(d, s);
  ...
}

もし d = s としたら,ポインタの値はコピーされるが,文字列の内容はコピーされない.

文字列の比較もまた,関数が必要である.次のプログラムは文字列 s1, s2 を比較している.関数strcmpは文字列s1が文字列s2よりも辞書順で先であれば正の値を,等しければ0を,辞書順で後であれば負の値を返す.

#include <stdio.h>
#include <string.h>

int main(int argc, const char *argv[]) {
  char s1[] = "apple";
  char s2[] = "orange";
  int c = strcmp(s1, s2);
  if (c > 0) {
    printf("s1 > s2\n");
  else {
    if (c == 0) {
      printf("s1 == s2\n");
    }
    else {
      printf("s1 < s2\n");
    }
}

文字列については,ひとまずこの程度知っておけばよかろう.C言語はあまり文字列処理に向いていない.もしテキスト処理が必要になったら,C言語は第一選択肢からは外すべきである.例えばAwk言語は,学習しやすく(数時間で習得できるだろう),かつ十分に強力である.
Comments