🇯🇵 日本語 | 🇺🇸 English

第23回 文字列

C言語の文字列(char配列)の扱い方。strcpy, strlen, strcmp等の文字列関数。

📖 このページで覚えること
✅ 最低限ここだけ覚える
  • 文字列 = char 配列 + 末尾 \0
  • printf("%s", s); で表示
  • char の実体は整数 (ASCIIコード)
  • strlen, strcpy, strcmp<string.h>
⭐ 余裕があれば読む
  • 大文字小文字変換 c + ('a'-'A')
  • strcpy は危険、snprintf を使う
  • 日本語は char 1個に入らない
💪 初心者は1回で分からなくて普通
文字列はポインタと配列の両方が絡むので、2つの概念が未消化だと混乱しがちです。
再挑戦のステップ
  1. 配列 を先に理解 (char s[10] も普通の配列)
  2. ポインタ を学んでから戻ってくる
  3. 末尾の \0(ヌル終端)の図を覚える — 「ここで終わり」の目印
  4. char の実体は整数 (ASCII) と思い出す
  5. わからない関数 (strlen など) は先に使い方だけ覚える
💡 コツ: "Hello" は実は {'H','e','l','l','o','\0'} の6バイト配列。文字列=配列+終端、これだけ掴めばOK。

文字列は「char の配列」で表す

前回(第22回 文字(char型))で char1 文字 を入れる箱だと学びました。
1 文字を入れる箱を並べたもの = 配列、つまり char の配列 を使えば、複数の文字 = 文字列 が表現できます。
'c'
[0]
'o'
[1]
'f'
[2]
'f'
[3]
'e'
[4]
'e'
[5]
'\0'
[6]
char の箱を 7 個 並べて、文字列 "coffee" を表現
ポイント:文字列の 最後には必ず '\0'(ヌル文字) を置きます。「ここで文字列が終わり」の目印で、これがないと printf がどこまで出力していいか分かりません。
char name[20] = "coffee";   // char の箱を 20 個用意(最大19文字 + '\0')
printf("%s\n", name);       // → coffee
%s は文字列用の書式指定子(string の s)。配列名だけを渡します(先頭の箱の住所が渡る)。

文字配列とメモリ配置

文字列 "Hello" がメモリにどう並ぶかを見てみましょう。
char msg[6] = "Hello"; ← 6バイト確保される(5文字 + '\0')
サイズに注意!「Hello」5文字でも、終端のヌル文字('\0')を含めて6バイト必要です。配列サイズが足りないとバッファオーバーフローのバグになります。

文字列の入出力

文字列を入出力するには %s を使います。scanfでは & を付けないのが特徴!
char name[20];
printf("名前は? ");
scanf("%s", name); // & は不要
printf("こんにちは、%sさん\n", name);
なぜ & が不要? 配列名 name は、それ自体が先頭要素のアドレスとして扱われます。だから & を付けなくてもアドレスが渡るのです。
⚠️ scanf("%s") の落とし穴:空白で区切られる&入力長のチェックをしません。長すぎる入力で配列をオーバーフローする危険があります(実務では fgets が安全)。

文字列の長さを数える

strlen(標準ライブラリ)を使えば簡単ですが、仕組みを知るため「自作版」を見てみましょう。
// '\0' が来るまで数える
int myStrlen(char s[]){
  int i = 0;
  while(s[i] != '\0') i++;
  return i;
}

int main(void){
  char msg[] = "Hello";
  printf("%d\n", myStrlen(msg)); // → 5
}
ヌル文字 '\0' がなぜ重要か分かりますね。終端を判定する目印として必須なのです。

string.h 関数一覧

#include <string.h> で使える、文字列操作の主要関数をまとめます。
関数機能使用例注意点
strlen(s)文字列の長さstrlen("abc") → 3'\0' は含まない
strcpy(dst, src)文字列コピーstrcpy(s, "Hello")dst に十分なサイズが必要
strncpy(dst, src, n)最大n文字コピーstrncpy(s, src, 10)バッファオーバーフロー防止
strcat(dst, src)文字列の連結strcat(s, " World")dst に連結後のサイズが必要
strcmp(s1, s2)文字列の比較strcmp(a, b) == 00なら等しい、正/負で辞書順
strncmp(s1, s2, n)先頭n文字を比較strncmp(s, "ab", 2)部分一致の判定に便利
strchr(s, c)文字を検索strchr(s, 'o')見つからなければNULL
strstr(s, sub)部分文字列を検索strstr(s, "llo")見つからなければNULL

strcpy と strcat の例

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

int main(void) {
    char greeting[50];
    strcpy(greeting, "Hello");     // greeting = "Hello"
    strcat(greeting, ", World!"); // greeting = "Hello, World!"
    printf("%s (%zu文字)\n", greeting, strlen(greeting));
    return 0;
}
== で文字列を比較しない!
if (s1 == s2) はアドレスの比較であり、文字列の内容は比較されません。
文字列比較には必ず strcmp(s1, s2) == 0 を使いましょう。
バッファオーバーフローに注意:
strcpystrcat は書き込み先のサイズをチェックしません。
十分な大きさの配列を用意するか、strncpy で最大文字数を制限しましょう。

自分で書いてみよう ― 文字列

文字列を表示し、長さを出力するプログラムです。
string.c
出力
「実行」を押してください...
💡 こんなことも試してみよう

関連する講座

繰り返し・配列・文字列
第20回 配列
C言語の配列の宣言・初期化・アクセス方法。メモリ配置も図解。
入門編
第4回 printf・scanf
C言語のprintf関数とscanf関数の使い方。書式指定子を一覧で解説。
発展編
第36回 ポインタの基礎
C言語のポインタをメモリ可視化で理解。アドレスと間接参照を図解。
← 前の講座
第22回 文字(char型)
次の講座 →
第24回 確認問題(文字列)

確認クイズ

この講座の理解度をチェックしましょう!

Q1. C言語の文字列の末尾には何がある?

改行文字 \n
ヌル文字 \0
スペース

C言語の文字列は必ずヌル文字 \0 で終端されます。これにより文字列の長さを判別できます。

Q2. "Hello" を格納するのに必要な配列サイズは?

5
6
7

"Hello" は5文字 + 終端の \0 で合計6バイト必要です。char s[6] 以上が必要です。

Q3. 文字列のコピーに使う関数は?

strcpy
strcmp
strlen

strcpy がコピー、strcmp が比較、strlen が長さ取得です。string.h をインクルードして使います。

この記事をシェア
X(Twitter)でシェア Facebookでシェア LINEで送る はてブ

この講座の理解を深めるおすすめ書籍

サイトで動きを理解し、書籍で演習量を補うと効果的です

📘
苦しんで覚えるC言語
MMGames 著
初心者向けの定番入門書。丁寧な解説で基礎を固められます。
Amazonで見る
📗
新・明解C言語 入門編
柴田望洋 著
図解が豊富で、演習問題も充実。大学の教科書としても採用多数。
Amazonで見る
📙
プログラミング言語C 第2版
B.W.カーニハン, D.M.リッチー 著
通称K&R。C言語の原典。基礎を終えた後のステップアップに最適。
Amazonで見る

※ 上記リンクはアフィリエイトリンクです。購入によりサイト運営を支援いただけます。