目的別のC言語文字列操作関数のクイックリファレンス
1. 文字列の宣言と初期化
文字列(文字の配列)を宣言し、初期化する基本的な方法です。
2. 文字列の長さ取得 (ヌル文字を除く)
文字列のヌル文字 ('\0'
) を除く文字数を取得します。
関数 | ヘッダ | 説明 | 使用例 |
---|---|---|---|
strlen |
<string.h> |
与えられたC文字列の長さを計算します。ヌル文字はカウントされません。 |
|
strnlen_s (C11 Annex K) / strnlen (POSIX, GNU) |
<string.h> |
最大長の制限付きで文字列の長さを計算します。バッファオーバーランを防ぐのに役立ちます。strnlen_s は Bounds-checking interface の一部です。 |
|
注意点: strlen
はヌル文字を探して文字列を走査します。ヌル終端されていない文字列を渡すと、バッファオーバーランを引き起こし、未定義動作となります 💥。strnlen
や strnlen_s
は最大チェック長を指定できるため、より安全です。
3. 文字列のコピー
ある文字列の内容を別の文字配列にコピーします。
関数 | ヘッダ | 説明 | 使用例 | 注意点 ⚠️ |
---|---|---|---|---|
strcpy |
<string.h> |
src 文字列(ヌル文字含む)を dest にコピーします。 |
|
非常に危険! dest のバッファサイズをチェックしません。src が dest より大きい場合、バッファオーバーフローが発生します。使用は避けるべきです。 |
strncpy |
<string.h> |
最大 n 文字を src から dest にコピーします。 |
|
src の長さが n 以上の場合、コピー結果がヌル終端されません!手動でのヌル終端が必要です。n 文字未満の場合はヌル文字でパディングされます。扱いにくい場合があります。 |
strcpy_s (C11 Annex K) |
<string.h> |
strcpy の安全なバージョン。コピー先のバッファサイズ (destsz ) を指定します。 |
|
C11 Annex K 準拠の処理系(例: MSVC)でのみ利用可能です。エラー処理が必要です。成功時に 0 を返します。 |
snprintf |
<stdio.h> |
書式指定文字列を使って安全に文字列をコピー(生成)します。実質的なコピーにもよく使われます。 |
|
推奨される安全な方法の一つです。戻り値で書き込みが成功したか、切り詰められたかを確認できます。 |
推奨: 可能な限り snprintf
や strcpy_s
(利用可能なら) を使用し、strcpy
の使用は避けてください。
4. 文字列の連結
ある文字列の末尾に別の文字列を追加します。
関数 | ヘッダ | 説明 | 使用例 | 注意点 ⚠️ |
---|---|---|---|---|
strcat |
<string.h> |
src 文字列を dest 文字列の末尾に追加します。dest の元のヌル文字は上書きされます。 |
|
非常に危険! strcpy 同様、dest のバッファサイズをチェックしません。連結後の文字列が dest の容量を超えるとバッファオーバーフローが発生します。使用は避けるべきです。 |
strncat |
<string.h> |
最大 n 文字を src から dest の末尾に追加します。常にヌル終端されます。 |
|
n は追加する最大文字数であり、dest の合計サイズではありません。残りのバッファサイズを正確に計算する必要があります。計算ミスがあると危険です。 |
strcat_s (C11 Annex K) |
<string.h> |
strcat の安全なバージョン。連結先のバッファサイズ (destsz ) を指定します。 |
|
C11 Annex K 準拠の処理系でのみ利用可能です。エラー処理が必要です。 |
snprintf (応用) |
<stdio.h> |
既存の文字列の末尾に追記する形でも利用できます。追記開始位置と残りサイズを管理する必要があります。 |
|
書き込み開始位置と残りサイズの計算がやや複雑ですが、非常に安全で柔軟な方法です。 |
推奨: snprintf
を応用するか、利用可能であれば strcat_s
を使用してください。strcat
は避けるべきです。
5. 文字列の比較
2つの文字列が等しいか、辞書順でどちらが先かを比較します。
関数 | ヘッダ | 説明 | 戻り値 | 使用例 |
---|---|---|---|---|
strcmp |
<string.h> |
s1 と s2 を辞書順で比較します。 |
|
|
strncmp |
<string.h> |
最大 n 文字まで、s1 と s2 を辞書順で比較します。 |
strcmp と同様。 |
|
strcasecmp (POSIX, GNU) / _stricmp (Windows) |
<strings.h> (POSIX) / <string.h> (Windows) |
strcmp と同様ですが、大文字と小文字を区別せずに比較します。 |
strcmp と同様。 |
|
strncasecmp (POSIX, GNU) / _strnicmp (Windows) |
<strings.h> (POSIX) / <string.h> (Windows) |
strncmp と同様ですが、大文字と小文字を区別せずに比較します。 |
strcmp と同様。 |
|
注意点: 比較関数は文字列の内容が等しいかどうかをチェックします。ポインタの値 (アドレス) が等しいかどうかを比較するには ==
を使用しますが、これは通常、文字列比較の目的ではありません。
6. 文字列の検索
文字列内から特定の文字または部分文字列を探します。
関数 | ヘッダ | 説明 | 戻り値 | 使用例 |
---|---|---|---|---|
strchr |
<string.h> |
文字列 s 内で文字 c が最初に現れる位置へのポインタを返します。 |
見つかった場合はその文字へのポインタ。見つからない場合は NULL 。 |
|
strrchr |
<string.h> |
文字列 s 内で文字 c が最後に現れる位置へのポインタを返します。 |
見つかった場合はその文字へのポインタ。見つからない場合は NULL 。 |
|
strstr |
<string.h> |
文字列 haystack 内で部分文字列 needle が最初に現れる位置へのポインタを返します。 |
見つかった場合は部分文字列の開始位置へのポインタ。見つからない場合は NULL 。 |
|
strpbrk |
<string.h> |
文字列 s1 内で、文字列 s2 に含まれるいずれかの文字が最初に現れる位置へのポインタを返します。 |
見つかった場合はその文字へのポインタ。見つからない場合は NULL 。 |
|
strspn |
<string.h> |
文字列 s1 の先頭から、文字セット s2 に含まれる文字のみで構成される部分の長さを返します。 |
条件に一致する先頭部分文字列の長さ (size_t )。 |
|
strcspn |
<string.h> |
文字列 s1 の先頭から、文字セット s2 に含まれる文字が最初に現れるまでの長さを返します。 |
条件に一致する先頭部分文字列の長さ (size_t )。 |
|
7. 文字列の分割 (トークン化)
文字列を区切り文字に基づいて部分文字列(トークン)に分割します。
関数 | ヘッダ | 説明 | 使用例 | 注意点 ⚠️ |
---|---|---|---|---|
strtok |
<string.h> |
文字列 str を区切り文字 delim で分割します。連続する呼び出しで次のトークンを取得します。 |
|
|
strtok_r (POSIX) / strtok_s (C11 Annex K, Windows) |
<string.h> |
strtok のリエントラント(再入可能)/ スレッドセーフなバージョン。内部状態を引数 saveptr (または context ) で管理します。 |
|
|
推奨: スレッドセーフ性が求められる場合や、より現代的なコードでは strtok_r
/ strtok_s
を使用してください。ただし、どちらも元の文字列を変更する点には注意が必要です。
8. 文字列の変換
文字列と数値の相互変換や、大文字/小文字の変換などを行います。
8.1. 文字列から数値への変換
関数 | ヘッダ | 説明 | 使用例 | 注意点 |
---|---|---|---|---|
atoi |
<stdlib.h> |
文字列を int 型に変換します。 |
|
エラーチェック機能がありません。変換できない場合やオーバーフローした場合の挙動が未定義または特定の値 (多くは0) を返すため、エラーと有効な値の区別が難しいです。非推奨。 |
atol |
<stdlib.h> |
文字列を long 型に変換します。 |
long val = atol("987654321"); |
atoi と同様の問題点があります。非推奨。 |
atof |
<stdlib.h> |
文字列を double 型に変換します。 |
double val = atof("3.14159"); |
atoi と同様の問題点があります。非推奨。 |
strtol |
<stdlib.h> |
文字列を long 型に変換します。基数指定とエラーチェックが可能です。 |
|
推奨。 エラーハンドリング (errno , endptr ) が可能です。基数 (2〜36) を指定できます。 |
strtoul |
<stdlib.h> |
文字列を unsigned long 型に変換します。 |
unsigned long val = strtoul("FF", NULL, 16); // val は 255 |
strtol と同様にエラーハンドリング可能。推奨。 |
strtoll (C99) |
<stdlib.h> |
文字列を long long 型に変換します。 |
long long val = strtoll("1234567890123", NULL, 10); |
strtol と同様にエラーハンドリング可能。推奨。 |
strtoull (C99) |
<stdlib.h> |
文字列を unsigned long long 型に変換します。 |
unsigned long long val = strtoull("FFFFFFFFFFFFFFFF", NULL, 16); |
strtol と同様にエラーハンドリング可能。推奨。 |
strtod |
<stdlib.h> |
文字列を double 型に変換します。エラーチェックが可能です。 |
|
strtol と同様にエラーハンドリング可能。推奨。 |
strtof (C99) |
<stdlib.h> |
文字列を float 型に変換します。 |
float val = strtof("1.618", NULL); |
strtod と同様。推奨。 |
strtold (C99) |
<stdlib.h> |
文字列を long double 型に変換します。 |
long double val = strtold("2.718281828459045", NULL); |
strtod と同様。推奨。 |
8.2. 数値から文字列への変換
関数 | ヘッダ | 説明 | 使用例 | 注意点 |
---|---|---|---|---|
sprintf |
<stdio.h> |
書式指定に従って、数値を文字列に変換し、指定されたバッファに書き込みます。 |
|
危険! バッファオーバーフローの可能性があります。書き込み先のバッファサイズをチェックしません。使用は避けるべきです。 |
snprintf |
<stdio.h> |
sprintf の安全なバージョン。書き込む最大文字数 (バッファサイズ) を指定します。 |
|
推奨。 バッファオーバーフローを防ぎます。戻り値で成功/失敗/切り詰めを確認できます。 |
8.3. 大文字/小文字変換
関数 | ヘッダ | 説明 | 使用例 | 注意点 |
---|---|---|---|---|
tolower |
<ctype.h> |
文字を小文字に変換します。引数は int です。 |
char lower_c = tolower('A'); // 'a' |
文字単位の変換です。文字列全体を変換するにはループが必要です。 |
toupper |
<ctype.h> |
文字を大文字に変換します。引数は int です。 |
char upper_c = toupper('a'); // 'A' |
文字単位の変換です。文字列全体を変換するにはループが必要です。 |
ループによる変換 | N/A | 文字列全体を大文字または小文字に変換します。 |
|
tolower /toupper に渡す前に unsigned char にキャストするのが安全です(特に負の char 値を扱う場合)。元の文字列を変更します。 |
9. メモリ操作関数 (文字列関連)
string.h
には、文字列だけでなく、任意のメモリブロックを操作する関数も含まれています。これらはヌル文字を特別扱いしないため、バイナリデータや途中にヌル文字を含む可能性のあるデータの扱いに便利です。
関数 | ヘッダ | 説明 | 使用例 | 対応する文字列関数 |
---|---|---|---|---|
memcpy |
<string.h> |
n バイトのメモリを src から dest にコピーします。コピー元とコピー先がオーバーラップしてはいけません。 |
|
strcpy , strncpy (ヌル終端なし) |
memmove |
<string.h> |
n バイトのメモリを src から dest にコピーします。コピー元とコピー先がオーバーラップしていても安全に動作します。 |
|
オーバーラップを考慮する場合の strcpy , strncpy |
memcmp |
<string.h> |
最初の n バイトについて、メモリブロック s1 と s2 を比較します。 |
|
strcmp , strncmp |
memchr |
<string.h> |
メモリブロック s の最初の n バイトの中から、文字 c (int として渡されるが unsigned char として扱われる) を検索します。 |
|
strchr |
memset |
<string.h> |
メモリブロック s の最初の n バイトを、文字 c (int として渡されるが unsigned char として扱われる) で埋めます。 |
|
特定の文字での初期化 (例: ゼロクリア) |
使い分け: 文字列として扱い、ヌル終端が保証されている場合は文字列関数 (strcpy
, strcmp
など) を使います。バイナリデータ、固定長データ、ヌル文字を含む可能性のあるデータ、またはパフォーマンスが非常に重要な場合はメモリ関数 (memcpy
, memcmp
など) を使います。オーバーラップの可能性がある場合は memmove
を使用します。
10. ワイド文字/マルチバイト文字操作
日本語のようなマルチバイト文字や、Unicode (UTF-16/UTF-32) を扱うための関数です。wchar.h
や stdlib.h
などに含まれます。
10.1. ワイド文字 (wchar_t) 操作
wchar_t
型 (通常 UTF-16 または UTF-32) の文字列を操作します。関数名は多くの場合、対応する char
関数の前に wcs
が付きます。
ワイド文字関数 | 対応するchar関数 | ヘッダ | 説明 |
---|---|---|---|
wcslen | strlen | <wchar.h> | ワイド文字列の長さを取得 |
wcscpy | strcpy | <wchar.h> | ワイド文字列をコピー (危険 ⚠️) |
wcsncpy | strncpy | <wchar.h> | 最大n文字のワイド文字列をコピー (ヌル終端注意) |
wcscpy_s | strcpy_s | <wchar.h> | 安全なワイド文字列コピー (C11 Annex K) |
wcscat | strcat | <wchar.h> | ワイド文字列を連結 (危険 ⚠️) |
wcsncat | strncat | <wchar.h> | 最大n文字のワイド文字列を連結 |
wcscat_s | strcat_s | <wchar.h> | 安全なワイド文字列連結 (C11 Annex K) |
wcscmp | strcmp | <wchar.h> | ワイド文字列を比較 |
wcsncmp | strncmp | <wchar.h> | 最大n文字のワイド文字列を比較 |
wcschr | strchr | <wchar.h> | ワイド文字列からワイド文字を検索 (前方) |
wcsrchr | strrchr | <wchar.h> | ワイド文字列からワイド文字を検索 (後方) |
wcsstr | strstr | <wchar.h> | ワイド文字列から部分ワイド文字列を検索 |
wcstok | strtok | <wchar.h> | ワイド文字列をトークン化 (非スレッドセーフ, 元文字列変更) |
wcstok_s | strtok_s | <wchar.h> | 安全なワイド文字列トークン化 (C11 Annex K) |
swprintf | sprintf | <wchar.h> | 書式付きでワイド文字列を生成 (サイズ指定版もあるが注意) |
swprintf (サイズ指定版) / snwprintf (非標準) | snprintf | <wchar.h> | 安全な書式付きワイド文字列生成 (標準では `swprintf` がサイズ指定可能) |
wcstol , wcstoul , wcstoll , wcstoull , wcstod , wcstof , wcstold | strtol 系 | <wchar.h> | ワイド文字列を数値に変換 |
#include <wchar.h>
#include <locale.h> // ロケール設定に必要
#include <stdio.h>
int main() {
setlocale(LC_ALL, ""); // システムのデフォルトロケールを設定
wchar_t wstr[] = L"これはワイド文字列です。"; // L プレフィックス
size_t len = wcslen(wstr);
// ワイド文字を出力するには printf 系ではなく wprintf 系を使う
wprintf(L"文字列: %ls\n", wstr);
wprintf(L"長さ: %zu 文字\n", len);
wchar_t copy[50];
// 安全なコピー (例: swprintf)
int result = swprintf(copy, sizeof(copy)/sizeof(wchar_t), L"コピー: %ls", wstr);
if (result > 0) {
wprintf(L"%ls\n", copy);
}
return 0;
}
10.2. マルチバイト文字 ⇔ ワイド文字 変換
システムの現在のロケール設定に基づいて、マルチバイト文字 (char
配列、例: UTF-8, Shift_JIS) とワイド文字 (wchar_t
配列) を相互に変換します。
関数 | ヘッダ | 説明 | 使用例 | 注意点 |
---|---|---|---|---|
mbtowc |
<stdlib.h> |
1文字のマルチバイト文字をワイド文字に変換します。 |
|
1文字ずつ変換する必要があります。状態を持つ場合があり、スレッドセーフではありません。 |
wctomb |
<stdlib.h> |
1文字のワイド文字をマルチバイト文字に変換します。 |
|
状態を持つ場合があり、スレッドセーフではありません。出力バッファサイズに注意。 |
mbstowcs |
<stdlib.h> |
マルチバイト文字列をワイド文字列に変換します。 |
|
変換する最大文字数を指定できます。ロケール依存です。 |
wcstombs |
<stdlib.h> |
ワイド文字列をマルチバイト文字列に変換します。 |
|
変換する最大バイト数を指定できます。ロケール依存です。 |
mbrtowc (C99) |
<wchar.h> |
mbtowc のリエントラント版。変換状態を引数で管理します。 |
より複雑な状態管理が必要な場合に使用。 | スレッドセーフ。状態 (mbstate_t ) を明示的に扱います。 |
wcrtomb (C99) |
<wchar.h> |
wctomb のリエントラント版。変換状態を引数で管理します。 |
より複雑な状態管理が必要な場合に使用。 | スレッドセーフ。状態 (mbstate_t ) を明示的に扱います。 |
mbsrtowcs (C99) |
<wchar.h> |
mbstowcs のリエントラント版。変換状態を引数で管理します。 |
より複雑な状態管理が必要な場合に使用。 | スレッドセーフ。状態 (mbstate_t ) を明示的に扱います。 |
wcsrtombs (C99) |
<wchar.h> |
wcstombs のリエントラント版。変換状態を引数で管理します。 |
より複雑な状態管理が必要な場合に使用。 | スレッドセーフ。状態 (mbstate_t ) を明示的に扱います。 |
重要: これらの変換関数は、setlocale(LC_CTYPE, "...")
で設定された現在のロケールに強く依存します。UTF-8 環境と Shift_JIS 環境では結果が異なります。特定のエンコーディング (例: UTF-8) を確実に扱いたい場合は、ロケールに依存しないライブラリ (例: ICU – International Components for Unicode) の使用を検討してください。
コメント