★文字と文字列(文字列2)★


では続いて、「数値」と同じように「文字列」をscanfで入力してみます。


<sample program 082-01>

#include <stdio.h>

#define MAX_STRING 10

int main(void)
{
    char str[MAX_STRING];

    scanf("%s", str);

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

    return 0;
}

<実行結果>

Hello ←scanfの入力
Hello
続行するには何かキーを押してください・・・

scanfで入力する時も「%s」を使えば入力出来ます。

ここでscanfの行を注意して見てください。

配列「str」の前に「&」が付いていません。

「&」を付けていても動作するのですが、「文字列」を表示する時には付けていないことが多いため、今後もサンプルでは付けないようにしておきます。

※このことについては、ずっと後に出てくる「ポインタ」という項目で説明します。


前回の説明の中で、最大文字数が10なので10文字くらい入りそうだと書きました。

作ったプログラムを実行する時に、誰もが正しく使ってくれるとは限りません

10文字を超えて入力するとどうなるか試してみましょう。

<実行結果>

abcdefghijklmnopqrstuvwxyz ←scanfの入力
abcdefghijklmnopqrstuvwxyz

※ここまで表示された時点で↓のダイアログが表示される。

続行するには何かキーを押してください・・・

これは要するに「まともに動かなかった」ということです。

10文字程度しか容量の無い入れ物に26個もデータを入れることは出来ません。

用意した配列の枠を超えてデータが入力されるため、他のデータが入る領域を犯して破壊する可能性があります。

では、10文字ギリギリではどうでしょうか?

やってみてください。

<実行結果>

0123456789 ←scanfの入力
0123456789

※ここまで表示された時点で↓のダイアログが表示される。

続行するには何かキーを押してください・・・

10文字でもダメでしたね・・・

では、9文字ではどうでしょう?

<実行結果>

123456789 ←scanfの入力
123456789
続行するには何かキーを押してください・・・

問題なく動作します。

この状況を説明するために、配列の中身を覗いてみましょう。

まずは、宣言したばかりの配列の中身を見てみます。

基本的に初期値が入っていない変数や配列の中身は「不定」です。

どんなものが入っているのでしょうか。

for文を使って、配列の中身を1つずつ「文字」として表示してみます。

<sample program 082-02>

#include <stdio.h>

#define MAX_STRING 10

int main(void)
{
    char str[MAX_STRING];

    int i;

    for (i = 0; i < MAX_STRING; i++) {
        printf("%c\n", str[i]);
    }

    return 0;
}

<実行結果>

フ
フ
フ
フ
フ
フ
フ
フ
フ
フ
続行するには何かキーを押してください・・・

私の実行環境では、カタカナの'フ'が10個表示されました。

※皆さんの環境では異なる結果になるかもしれません。

「10進数」で表示してみましょう。

<sample program 082-03>

#include <stdio.h>

#define MAX_STRING 10

int main(void)
{
    char str[MAX_STRING];

    int i;

    for (i = 0; i < MAX_STRING; i++) {
        printf("%d\n", str[i]);
    }

    return 0;
}

<実行結果>

-52
-52
-52
-52
-52
-52
-52
-52
-52
-52
続行するには何かキーを押してください・・・

-52という「数値」が表示されました。

文字コード表」に-52番なんてありましたでしょうか。

なぜこの数になっているか、分かりますか?

とりあえず考えてみてください。

ヒント「char型は8ビットの変数」









































解答です。

char型は8ビットの変数です。

符号ありだと「-128から127」まで、符号なしだと「0から255」まで表現出来ます。

そして、文字コード表は符号なしの数で表示されています。

符号ありの-52は符号なしで表現するといくらになるでしょうか。

2の補数を使った2進数で-52を表現すると、

  1100 1100

です。

マイナスの表現」というコラムでの書き方だとこうなります。

   1の位 が 0個 =    0
   2の位 が 0個 =    0
   4の位 が 1個 =    4
   8の位 が 1個 =    8
  16の位 が 0個 =    0
  32の位 が 0個 =    0
  64の位 が 1個 =   64
−128の位 が 1個 = −128

全部合計すると-52です。

一方同じビット列を符号なしで計算するとこうなります。

   1の位 が 0個 =    0
   2の位 が 0個 =    0
   4の位 が 1個 =    4
   8の位 が 1個 =    8
  16の位 が 0個 =    0
  32の位 が 0個 =    0
  64の位 が 1個 =   64
 128の位 が 1個 =  128

全部合計すると204です。

文字コード表」の204番を見てください。

カタカナの'フ'ですね。

少し「文字列」から離れましたが、なぜそうなっているのかといった、仕組みを考えることは重要なことです。


今回はたまたまカタカナの'フ'が入っていましたが、初期値が入っていない配列の中身は不定です。

初期値を入れた状態も見てみましょう。

<sample program 082-02>のプログラムに、scanfで"ABC"と入力してみます。

<sample program 082-04>

#include <stdio.h>

#define MAX_STRING 10

int main(void)
{
    char str[MAX_STRING];

    int i;

    scanf("%s", str);

    for (i = 0; i < MAX_STRING; i++) {
        printf("%c\n", str[i]);
    }

    return 0;
}

<実行結果>

ABC ←scanfの入力
A
B
C

フ
フ
フ
フ
フ
フ
続行するには何かキーを押してください・・・

"ABC"は表示されましたが、"ABC"の後ろに空白があります。

「数値」として見てみましょう。

上のプログラムの「%s」を「%d」に変えて、同じように"ABC"と入力してみます。

<sample program 082-02>のプログラムに、scanfで"ABC"と入力してみます。

<sample program 082-05>

#include <stdio.h>

#define MAX_STRING 10

int main(void)
{
    char str[MAX_STRING];

    int i;

    scanf("%s", str);

    for (i = 0; i < MAX_STRING; i++) {
        printf("%d\n", str[i]);
    }

    return 0;
}

<実行結果>

ABC ←scanfの入力
65
66
67
0
-52
-52
-52
-52
-52
-52
続行するには何かキーを押してください・・・

'A'の文字コードは「10進数」で65です。

'B'は66、'C'は67ですね。

"ABC"の後ろには0がありました。

文字コードの0を確認してください。

NUL」と書いてあります。

これは「ヌル」と読み、「NULL」と書くことも多いです。

色々な意味があるのですが、「文字」としての「ヌル」は「ヌル文字」と言って、文字列の最後を表す文字です。

「文字列」の初期値を入れたり、入力をした際には自動的に「ヌル文字」が文字列の最後に入ります

そのため、10個分の配列を準備したとしても、「ヌル文字」分を考慮すると9文字しか入らないことになります。


初期値を設定した場合も見てみましょう。

<sample program 082-06>

#include <stdio.h>

#define MAX_STRING 10

int main(void)
{
    char str[MAX_STRING] = "ABC";

    int i;

    for (i = 0; i < MAX_STRING; i++) {
        printf("%d\n", str[i]);
    }

    return 0;
}

<実行結果>

65
66
67
0
0
0
0
0
0
0
続行するには何かキーを押してください・・・

初期値を設定した場合は、配列の空いている部分に全てゼロが入ります。

初期値の文字数を10文字にしてみましょう。

<sample program 082-07>

#include <stdio.h>

#define MAX_STRING 10

int main(void)
{
    char str[MAX_STRING] = "ABCDEFGHIJ";

    int i;

    for (i = 0; i < MAX_STRING; i++) {
        printf("%d\n", str[i]);
    }

    return 0;
}

コンパイルエラーで実行出来ません。

エラー内容を見てみましょう。

  error C2117: 'str': 指定された配列には、初期化子が多すぎます。

最初の行にあるとおり、初期化子(初期化に使っているデータ)の数が多いのです。

10個の配列に10文字入れようとしていますが、「ヌル文字」分が考慮されておらず、入りきらないのでエラーとなっています。


C言語で「文字列」を扱う際には、「ヌル文字」の存在を常に頭に置いてください。

「ヌル文字」を利用するプログラムも後々やっていきます。


ここで、コラムを3つ紹介しますので、順に読んでください。

1.エスケープシーケンス

2.scanfと文字列

3.文字列入力関数


次へ

戻る

目次へ