授業/C言語基礎/文字列 のバックアップ(No.2)


これまで、文字列は、ダブル・クォーテーション " で囲まれたもので、printf関数またはscanf関数に渡すだけのものでした。

実は、文字列は、文字を集めて並べたデータです。

そこで、まずは文字について説明し、それから、文字列について説明します。

文字はchar型の変数に格納する

文字を格納するための変数の型はchar型です。

  char s[] = "ABC";

文字はシングル・クォーテーションで囲む

文字列はダブル・クォーテーションで囲みましたが、文字はシングル・クォーテーション ' で囲みます。

  char s[] = "ABC";

  printf(">> %s\n", s);

文字を出力するときの変換指定子は %c

printf関数で、変数に格納された文字を出力するときは、変換指定子を%cとします(プログラム1)。

  char s[] = "ABC";
  int i, len;

  len = sizeof(s) / sizeof(s[0]);
  for (i = 0; i < len; i++) {
    printf("%d\n", s[i]);
  }

演習1

プログラム1を作成し、実行結果を確認せよ。

エスケープ・シーケンスは1文字

改行 \n、バックスラッシュ \\、ダブルクオーテーション \" などのエスケープ・シーケンスは、1文字として扱われます(プログラム2)。

luna% a.out
>> 4
64
65
66
0

演習2

プログラム2を作成し、実行結果を確認せよ。

文字列はchar型の配列に格納する

文字列は、複数の文字を並べたものであり、char型の配列として扱われます。

  char s[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  s[7] = '\0';

  printf(">> %s\n", s);

文字列を出力するときの変換指定子は %s

printf関数で、変数に格納された文字列を出力するときは、変換指定子を%sとします(プログラム3)。

luna% a.out
>> ABCDEFG

演習3

プログラム3を作成し、実行結果を確認せよ。

文字列の最後は '\0'

実は、文字列の最後には、ヌル文字 \0 という文字(エスケープ・シーケンス)があります。

つまり、"ABC"という文字列は、文字 'A'、文字 'B'、文字 'C'、そしてヌル文字 '\0' から成る長さ4の文字列です。

ヌル文字は表示して確認することはできませんが、if文で比較すると確認できます(プログラム4)。

  char s[4];

  s = "ABC";

  printf(">> %s\n", s);

演習4

プログラム4を作成し、実行結果を確認せよ。

初期化のとき以外は文字列を直接代入できない

上のプログラムのように、文字列を格納する変数を宣言すると同時に初期化するときには、変数に文字列を直接代入できますが、それ以外のときは文字列を直接代入することができません(プログラム5)。

  char s[4];

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

  printf(">> %s\n", s);

演習4

プログラム4をプログラム5に変更し、コンパイル結果を確認せよ。

文字を一つずつ代入して文字列を作る

文字列は文字の配列ですから、配列の要素を一つずつ代入するように、文字を一つずつ代入することができます。 このとき、最後にヌル文字を追加するのを忘れないようにしましょう(プログラム6)。

  char s[8];

  scanf("%s", s);
  printf(">> %s\n", s);

演習6

プログラム6を作成し、実行結果を確認せよ。

文字列をキーボードから入力する

scanf関数を使って、文字列をキーボードから入力することができます。 変換指定子にはprintf関数と同じ %s を使いますが、代入される変数の前にアンパサンド & をつけません。

  char s[8];

  scanf("%7s", s);
  printf(">> %s\n", s);

ただし、文字列の長さが入力された文字数より大きくないと(入力された文字数+1以上でないと)、セグメント・エラーになる可能性があります。 そこで、変換指定子に桁数を指定して、入力される文字列の長さを制限します(プログラム7)。

luna% a.out
1234567890
>> 1234567

このプログラムを実行し、"1234567890"と入力すると、結果は次のようになります。

#include <stdio.h>

int strlen(char s[]) {
  int i = 0;

  while (s[i] != '\0') {  i++; }

  return i;
}

int  main(void) {
  char s[16];
  int len;

  printf("英単語を入力してください");
  scanf("%15s", s);

  len = strlen(s);
  printf("%d文字\n", len);

  return 0;  
}

8文字目はヌル文字になるので、7文字しかないように見えます。

演習7

プログラム7を作成し、実行結果を確認せよ。

文字列操作関数を使うときはstring.hをインクルードする

文字列を操作するための関数が用意されていて、string.hをインクルードすることで使えるようになります。

#include <string.h>

文字列の長さを調べる strlen関数

文字列の長さを調べるには、strlen関数を使います。

strlen関数は、文字列を引数として受け取り、その長さをint型で返します。

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

int main(void) {
  char s[16] = "ABC";
  char t[16];
  int len;

  len = strlen(s);  // 文字列sの長さを調べる
  printf(">> %d\n", len);

  strcpy(t, s);  // 文字列sを文字列tにコピー(代入)する
  printf(">> %s\n", t);

  strncpy(t, s, 2);  // 文字列sを文字列tに先頭から最大2文字までコピー(代入)する
  printf(">> %s\n", t);

  strcat(s, "DEF");  // 文字列sの後ろに文字列"DEF"を連結する
  printf(">> %s\n", s);

  strncat(s, "GHI", 2);  // 文字列sの後ろに文字列"GHI"のうち先頭から最大2文字まで連結する
  printf(">> %s\n", s);

  if (strcmp(s, "ABCDEFGH") == 0) { // 文字列sと文字列"ABCDEFGH"を比較する
    printf(">> 同じ\n");
  } else {
    printf(">> 同じでない\n");
  }

  if (strcmp(s, "ABCXYZ", 3) == 0) { // 文字列sと文字列"ABCXYZ"を先頭から最大3文字まで比較する
    printf(">> 同じ\n");
  } else {
    printf(">> 同じでない\n");
  }

  return 0;
}

まとめ

練習問題

問題1

長さ64の文字列sを宣言し、sをキーボードから入力すると、文字列sの長さを出力するプログラムを作成せよ。 ただし、strlen関数を用いてはならない。

問題2

長さ64の文字列s1, s2を宣言し、s1をキーボードから入力すると、s1をs2にコピーしてs2を出力するプログラムを作成せよ。 ただし、strcpy関数を用いてはならない。

問題3

長さ64の文字列sを宣言し、入力された文字列が"Hello"なら「こんにちは」と出力するプログラムを作成せよ。 ただし、strcmp関数を用いてはならない。

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS