🔤 文字列
🎯 文字列の初期化の書き方を使い分け、代入できない理由を説明できる
ソースコードにダブルクォートで書いた "hello" を文字列リテラルと呼びます。文字列の初期化には、いくつかの書き方があります。
char a[6] = "hello"; // 大きさを自分で指定
char b[] = "hello"; // 大きさは自動で6になる
char c[20] = "hello"; // 余裕を持たせる(残りは0)
char d[4] = {'c', 'a', 't', '\0'}; // 1文字ずつ並べるb の書き方が便利です。文字数を数えなくても、コンパイラが '\0' のぶんを含めて大きさを決めてくれます。文字列を後から書き換える予定がないなら、これが最も安全です。
c のように大きく取るのは、あとで長い文字列を入れ直す予定があるときです。余った要素は 0 で埋まります。
代入はできない
初期化はできるのに、あとから代入はできません。
char s[10] = "hello";
s = "world"; // ← コンパイルエラー!配列そのものへの代入がCでは許されていないからです(t08-05で見たとおりです)。文字列を入れ直したいときは、専用の関数 strcpy を使います。
#include <stdio.h>
#include <string.h>
int main(void)
{
char s[10] = "hello";
strcpy(s, "world"); // 中身を丸ごと入れ替える
printf("%s\n", s); // world
return 0;
}strcpy(コピー先, コピー元) の順番です。「代入と同じで左が行き先」と覚えると迷いません。ただしこの関数には大きな落とし穴があり、t09-05でたっぷり扱います。
比べるのも == ではできない
if (s == "world") // ← これは中身を比べていない!この書き方はコンパイルが通ることもありますが、文字列の中身を比較していません。中身を比べるには strcmp を使います。詳しくは次のトピックです。
どの書き方を選ぶか
書き換える予定がないなら char s[] = "..."、あとで入れ替えるなら大きめに取って char s[64] = "...";。この2つを押さえておけば十分です。よくある失敗は、char s[] = "hi";(大きさ3)に対して、あとから長い文字列を strcpy してしまうこと。宣言したときの文字数がそのまま上限になっているので、確実に溢れます。「あとで入れ替えるなら、最初から大きく取る」と覚えてください。
罠・注意
char s[3] = "hello"; は溢れています。コンパイラが警告を出すこともありますが、黙って通る環境もあります。'\0' を自分で書かないと文字列になりません。{'c','a','t'} は「文字が3つ並んだ配列」であって文字列ではありません。"hello" と書いた部分)は、書き換えてはいけない場所に置かれることがあります。配列にコピーした s は書き換えて構いませんが、リテラルを直接指す使い方は第2部まで待ってください。char b[] = "hi"; は大きさ3、char b[10] = "hi"; は大きさ10です。sizeof の結果が変わる点に注意しましょう(strlen はどちらも2です)。まとめ: 文字列の初期化は char s[] = "..." が基本。あとからの代入はできず、入れ直しは strcpy、比較は strcmp を使います。
もっと先へ:ポインタ・メモリ・ファイル入出力・セキュアコーディングを含む全26トラックと、段位検定・模試のフルセットは完全版に収録しています。