【6日でできるC言語入門】文字列とポインタ

 C言語における文字列は、char型の配列として扱います。そして、文字列を操作する際にはchar型ポインタが大きな役割を果たします。配列とポインタの関係を理解することで、C言語の文字列操作がより柔軟かつ効果的に行えるようになります。ここでは、ポインタを使った文字列の扱い方や、代表的な文字列関数について、図やサンプルプログラムを交えながら詳しく解説します。

1.文字列とポインタの基本

1.1. 文字列とchar型配列

C言語で文字列を表現する最も基本的な方法は、char型配列です。
以下の例を見てみましょう。

サンプルプログラム1:char型配列による文字列

プロジェクト/ファイル名: Lesson56_1/main.c

#include <stdio.h>

int main(void) {
    char greeting[11] = "こんにちは";
    printf("greetingの内容:%s\n", greeting);
    return 0;
}

実行結果

greetingの内容:こんにちは

解説
 配列greetingは、'こ', 'ん', 'に', 'ち', 'は', '\0' という文字データで構成されています。配列名は、その先頭アドレス(ポインタ)を示します。

1.2. 文字列リテラルとポインタ

C言語では、文字列リテラルもchar型ポインタで参照できます。
次の例を見てください。

サンプルプログラム2:文字列リテラルとポインタ

プロジェクト/ファイル名: Lesson56_2/main.c

#include <stdio.h>

int main(void) {
    const char *message = "おはようございます";
    printf("messageの内容:%s\n", message);
    return 0;
}

実行結果

messageの内容:おはようございます

解説
 ここで message は文字列リテラル"おはようございます"の先頭アドレスを指しています。constを付けるのが一般的です(リテラルは書き換え禁止)。

表:char型配列とchar型ポインタの比較

宣言方法アクセス方法特徴
char配列char s[10];s, s[0]サイズ固定。書き換え可能。
char型ポインタ(リテラル)const char *p = "...";p, p[0]リテラルの書き換え不可。柔軟な参照が可能。

2.文字列操作関数とポインタ

2.1. 文字列のコピー・結合・長さ取得

C言語には標準ライブラリstring.hで用意された便利な文字列関数が多数あります。
ここではstrcpystrcatstrlenを紹介します。

サンプルプログラム3:文字列のコピー・結合・長さの取得

プロジェクト/ファイル名: Lesson56_3/main.c

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

int main(void) {
    char city[20];
    int length;

    // 文字列のコピー
    strcpy(city, "東京");
    printf("city=%s\n", city);

    // 文字列の結合
    strcat(city, "駅");
    printf("city=%s\n", city);

    // 文字列の長さ
    length = strlen(city);
    printf("文字列の長さは%dです。\n", length);

    return 0;
}

実行結果

「SDLチェック」を「いいえ」にして、プログラムを実行します。

city=東京
city=東京駅
文字列の長さは6です。。

表:主な文字列操作関数

関数名書式説明使用例
strcpystrcpy(char* dst, const char* src);文字列srcをdstへコピーstrcpy(s, "Hello");
strcatstrcat(char* dst, const char* src);文字列srcをdstに連結strcat(s, "World");
strlenstrlen(const char* s);文字列sの長さを取得int n = strlen(s);

2.2. 文字列比較関数

文字列の内容が等しいかどうかはstrcmp関数で調べます。

サンプルプログラム4:文字列の比較

プロジェクト/ファイル名: Lesson56_4/main.c

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

int main(void) {
    char pass1[20], pass2[20];
    printf("パスワードを入力してください:");
    scanf("%s", pass1);
    printf("もう一度入力してください:");
    scanf("%s", pass2);

    if (strcmp(pass1, pass2) == 0) {
        printf("パスワードが一致しました。\n");
    } else {
        printf("パスワードが一致しません。\n");
    }
    return 0;
}

実行結果

「SDLチェック」を「いいえ」にして、プログラムを実行します。

パスワードを入力してください:password
もう一度入力してください:password
パスワードが一致しました。

表:文字列比較関数

関数名書式説明使用例
strcmpstrcmp(const char* s1, const char* s2);s1とs2が同じなら0、違えば非0を返すstrcmp(a, b) == 0

3.文字列とポインタを使った応用

3.1. 文字列を数値に変換(atoi, atof)

C言語では文字列から数値への変換もポインタを使って行います。

サンプルプログラム5:文字列から数値への変換

プロジェクト/ファイル名: Lesson56_5/main.c

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    char numstr[] = "5678";
    int num;
    num = atoi(numstr);
    printf("数値は%dです。\n", num);
    return 0;
}

実行結果

数値は5678です。

表:文字列→数値変換関数

関数名書式説明使用例
atoiatoi(const char* s);文字列sを整数値(int)に変換int n = atoi(s);
atofatof(const char* s);文字列sを実数値(double)に変換double d = atof(s);

3.2. 数値を文字列に変換(sprintf)

printf と同じ書式で、結果を文字列として保存できます。

サンプルプログラム6:数値を文字列に変換

プロジェクト/ファイル名: Lesson56_6/main.c

#include <stdio.h>

int main(void) {
    char result[20];
    int score = 88;
    sprintf(result, "点数は%d点です。", score);
    puts(result);
    return 0;
}

実行結果

「SDLチェック」を「いいえ」にして、プログラムを実行します。

点数は88点です。

4.文字列操作の注意点とセキュリティ

4.1. 配列サイズの超過に注意

配列サイズを超えて文字列をコピー・連結すると、メモリ破壊(バッファオーバーフロー)が発生します。

char s[5];
strcpy(s, "123456789"); // 危険!サイズ超過

4.2. セキュリティ上の配慮

 最近のC言語開発環境では、scanfgets などの関数は安全性の観点から推奨されないことがあります。より安全な入力関数(例:fgets)や、配列サイズを明示するバージョン(例:strncpy:読み方:ストリングNコピー)を使いましょう。

まとめ

 C言語での文字列操作には、char型配列とポインタが密接に関わっています。ポインタを使うことで、柔軟かつ効率的な文字列処理が可能になりますが、配列サイズや安全性にも注意する必要があります。文字列関数の使い方とポインタの関係をしっかり理解し、安全なプログラムを書けるようにしましょう。