C言語の学習を続けます。前回は「動的メモリ管理」と「構造体」を解説しました。
今回は、C言語でのより高度なデータ操作とファイル処理に不可欠な「文字列と文字配列」および「ファイルI/O」について解説します。
6. 文字列と文字配列 (Strings and Character Arrays)
C言語には、C#やJavaのような専用のString型は存在しません。文字列は、文字の配列として扱われ、その終端は必ず**ナル文字(\0
)**で示されます。
📝 文字列の宣言と初期化
文字列は、char
型の配列として宣言します。
C
#include <stdio.h>
// 1. 文字配列として宣言(要素数にナル文字の分も含める)
char str1[10] = {'H', 'e', 'l', 'l', 'o', '\0'};
// 2. 文字列リテラル(ダブルクォーテーション)で初期化
// コンパイラが自動的にナル文字(\0)を末尾に追加してくれる
char str2[] = "World";
// 3. ポインタを使った宣言(文字列定数へのポインタ)
// str3が指す文字列データ自体は変更できないことが多い
char *str3 = "C Language";
printf("文字列1: %s\n", str1); // %s は文字列全体を出力するためのフォーマット指定子
printf("文字列2: %s\n", str2);
📏 文字列操作 (string.h
)
文字列の操作(長さの取得、コピー、連結など)は、標準ライブラリの <string.h>
に含まれる関数を使って行います。
関数 | 目的 | 説明 |
strlen(str) | 長さの取得 | 文字列のナル文字を除く長さを返します。 |
strcpy(dest, src) | コピー | src の内容を dest にコピーします。dest はsrc より十分な大きさが必要です。 |
strcat(dest, src) | 連結 | dest の末尾に src の内容を連結します。dest のメモリが足りるか注意が必要です。 |
strcmp(str1, str2) | 比較 | 2つの文字列が等しいか比較します。等しい場合は 0 を返します。 |
Google スプレッドシートにエクスポート
C
#include <string.h>
char buffer[50] = "Hello "; // 連結のために十分なサイズを確保
char *word = "World!";
// 文字列の連結
strcat(buffer, word);
printf("連結後: %s\n", buffer); // 出力: Hello World!
// 文字列の長さ
size_t length = strlen(buffer);
printf("長さ: %zu\n", length); // 出力: 12
⚠️ 注意: strcpy
やstrcat
を使う際は、必ずコピー先(dest
)の配列が十分な大きさを持っていることを確認してください。サイズが不足するとバッファオーバーフローを引き起こし、深刻なバグやセキュリティ問題の原因となります。
7. ファイル I/O (Input/Output)
C言語でファイル(テキストファイルやバイナリファイル)を読み書きするには、標準ライブラリの <stdio.h>
にある関数を使用します。ファイル操作は、以下の3つの手順が基本となります。
- ファイルを開く (
fopen
) - 読み書きを実行 (
fprintf
,fscanf
,fgetc
,fputc
など) - ファイルを閉じる (
fclose
)
📂 ファイル操作の基本
ファイル操作では、FILE
型のポインタを使用して、開いたファイルへのアクセスを管理します。
C
#include <stdio.h>
int main() {
FILE *fp; // ファイルポインタを宣言
char filename[] = "test.txt";
// 1. ファイルを開く ("w": 書き込みモード。ファイルが存在すれば上書き)
fp = fopen(filename, "w");
if (fp == NULL) {
perror("ファイルのオープンに失敗しました");
return 1;
}
// 2. ファイルにデータを書き込む (printfと似た fprintf を使用)
fprintf(fp, "C言語でファイル処理を学習中です。\n");
fprintf(fp, "これは2行目です。\n");
// 3. ファイルを閉じる(必ず行う)
fclose(fp);
printf("ファイル '%s' への書き込みが完了しました。\n", filename);
return 0;
}
🗝️ ファイルのオープンモード
モード | 目的 | 特徴 |
"r" | 読み込み (Read) | ファイルが存在しない場合、オープン失敗。 |
"w" | 書き込み (Write) | ファイルが存在すれば内容を破棄して新規書き込み。 |
"a" | 追記 (Append) | ファイルの末尾に内容を追加。ファイルが存在しなければ新規作成。 |
"rb" / "wb" | バイナリ読み書き | 画像や実行ファイルなど、バイナリデータを扱う場合に使用。 |
Google スプレッドシートにエクスポート
📚 ファイルからの読み込み
fscanf
や fgets
を使ってファイルからデータを読み込みます。
C
#include <stdio.h>
int main() {
FILE *fp;
char buffer[100]; // 読み込み用バッファ
fp = fopen("test.txt", "r"); // 読み込みモード
if (fp == NULL) {
perror("ファイルのオープンに失敗しました");
return 1;
}
// fgetsを使って1行ずつ読み込む(EOF: End Of Fileに達するまで)
printf("\n--- ファイルの内容 ---\n");
while (fgets(buffer, sizeof(buffer), fp) != NULL) {
printf("%s", buffer);
}
fclose(fp);
return 0;
}
ファイルI/Oと文字列操作は、C言語で実用的なアプリケーションを作る上で避けて通れない分野です。特にポインタやメモリ管理と密接に関連するため、バッファサイズには十分注意を払いましょう。