区分 | 関数 | 使用方法 |
---|---|---|
文字数の取得 | strlen | 文字列の長さを取得する |
_scprintf | 書式設定された文字列内の、文字数を返す | |
_strncnt | 指定した文字数内の文字の、バイト数を返す | |
書式の設定 | sprintf | 文字列に書式付きデータを書き込む |
vsprintf | 引数リストへのポインターを使用して、書式付き出力を書き込む | |
vsnprintf | 引数リストへのポインターを使用して、書式付き出力を書き込む | |
sscanf | 指定した長さの書式付きデータを、標準入力ストリームから読み取る | |
_snscanf | 指定した長さの書式付きデータを、標準入力ストリームから読み取る | |
strftime | 日付と時刻の文字列の書式を設定する | |
文字の追加 | strcat | 文字列を、別の文字列に追加する |
strncat | 文字列の文字を追加する | |
文字のコピー | strcpy | 文字列の全体を、別の文字列にコピーする |
strncpy | 文字列の一部を、別の文字列にコピーする | |
_strdup | 文字列を複製する | |
文字の検索 | strtok | 文字列の次のトークンを検索する |
_strnextc | 文字列の次の文字を検索する | |
strchr | 指定した文字が最初に出現する位置を、文字列内で検索する | |
strrchr | 指定した文字が最後に出現する位置を、文字列内で検索する | |
strstr | 指定した文字列が最初に出現する位置を、別の文字列内で検索する | |
strcspn | 指定した文字セットの文字が最初に出現する位置を検索し、そのインデックスを返す | |
strpbrk | 指定した文字セットの文字が最初に出現する位置を検索し、その文字へのポインタを返す | |
strspn | 別の文字列内では見つからない文字の文字列が最初に出現する位置を、文字列内で検索する | |
_strspnp | 指定した一方の文字列の文字のうち、もう一方の指定した文字列にはない最初の文字へのポインターを返す | |
文字の変換 | _strlwr | 文字列を小文字に変換する |
_strupr | 文字列を大文字に変換する | |
_strset | すべての文字を、指定した文字に置換する | |
_strnset | 先頭のn文字を、指定した文字に置換する | |
strxfrm | ロケール固有の情報に基づいて、文字列を照合形式に変換する | |
文字列の比較 | strcmp | 2つの文字列を比較する |
strncmp | 2つの文字列の部分文字列を比較する | |
_stricmp | 大文字小文字に関係なく、2つの文字列を比較する | |
_strnicmp | 大文字小文字に関係なく、2つの文字列の部分文字列を比較する | |
strcoll | 現在のロケールの情報を使用して、2つの文字列を比較する | |
_strncoll | 現在のロケールの情報を使用して、2つの文字列の部分文字列を比較する | |
ポインターの操作 | _strinc | 文字列ポインターを、1文字進める |
_strdec | 文字列ポインターを、1文字前に移動する | |
_strninc | 文字列ポインターを、n文字進める | |
その他 | _strrev | 文字列の順序を逆にする |
strerror | エラー番号をメッセージ文字列にマップする |
size_t strlen( const char *str );strlen、wcslen、_mbslen、_mbslen_l、_mbstrlen、_mbstrlen_l | MSDN
char* s1 = "ABC"; wchar_t* w1 = L"ABC"; char* s2 = "あいう"; wchar_t* w2 = L"あいう"; size_t s1_len = strlen(s1); // 3 size_t w1_len = wcslen(w1); // 3 size_t s2_len = strlen(s2); // 6 size_t w2_len = wcslen(w2); // 3 size_t s1_size = sizeof(s1); // 4 (char*型のバイト数) size_t w1_size = sizeof(w1); // 4 (wchar_t*型のバイト数)
char *strcat( char *strDestination, // NULLで終わる追加先の文字列 const char *strSource // NULLで終わる元の文字列 );strcat、wcscat、_mbscat | MSDN
strDestinationの終端のNULLに上書きするように、strSourceを末尾に追加します。そしてstrDestinationのアドレスを返します。
char s[5] = "AA"; strcat(s, "BB"); // AABB\0 strcat(s, "CC"); // バッファオーバーラン発生
追加する文字列が大きすぎると、バッファがオーバーフローします。これを回避するには次のstrncat()を使用します。
char *strncat( char *strDest, // NULLで終わる追加先の文字列 const char *strSource, // NULLで終わる元の文字列 size_t count // 追加する文字数 );strncat、_strncat_l、wcsncat、_wcsncat_l、_mbsncat、_mbsncat_l | MSDN
strDestinationの終端のNULLに上書きするように、strSourceを最大count文字数だけ末尾に追加します。そしてstrDestinationのアドレスを返します。
char s1[5] = "AA"; strncat(s1, "BBBB", 2); // AABB\0 char s2[5] = "AA"; strncat(s2, "BBBB", 3); // バッファオーバーラン発生
追加する文字数をcountで制限できますが、制限を誤ればバッファオーバーランが発生します。
単純な処理ならば、配列としてアクセスすることで末尾に文字列を追加できます。
char s[5] = "AA";
s[2] = 'B';
s[3] = 'B';
s[4] = NULL; // "AABB\0"
sprintf()で書式設定することで、指定位置へ文字列を挿入できます。
char source[] = "ABCD"; char str[] = "xx"; // 挿入する文字列 int pos = 2; // 挿入する位置 char destination[256]; sprintf( destination, "%.*s%s%s", pos, // 精度指定で最大文字数を指定 source, // 前半部 str, // 挿入する文字列 source + pos // 後半部の位置までポインタをずらして指定 ); // "ABxxCD"insert a char in the middle of a string - C / C++
NULLの位置を移動することで、見かけ上切り詰められます。
char s[] = "ABCD";
s[2] = NULL; // "AB"
char *strcpy( char *strDestination, // コピー先のアドレス const char *strSource // コピー元の文字列のアドレス );strcpy、wcscpy、_mbscpy | MSDN
strSourceを終端のNULLも含めてstrDestinationへコピーし、strDestinationのアドレスを返します。
char source[] = "ABC"; char destination[256]; char* p = strcpy(destination, source); // destination[0] … 'A' // destination[1] … 'B' // destination[2] … 'C' // destination[3] … '\0' // destination[4] … ? // p == destination は、true
コピー先のstrDestinationに十分な領域がないとバッファオーバーランが発生します。これを防止するにはstrcpy_s()で、呼び出し時に領域のサイズを提供するようにします。
errno_t strcpy_s(
char *strDestination,
size_t numberOfElements, // コピー先バッファのchar単位のサイズ。つまり要素数
const char *strSource
);
strcpy_s、wcscpy_s、_mbscpy_s | MSDN
char source[] = "ABC"; char destination[256]; errno_t error = strcpy_s(destination, 256, source);
次のように_countofマクロを用いれば、要素数を明示する必要はありません。
errno_t error = strcpy_s(destination, _countof(destination), source);
またはテンプレート オーバーロードが有効ならば、要素数の指定すら不要です。
errno_t error = strcpy_s(destination, source);
もしくは_strdup()を用いれば、コピー先の指定すら不要です。
char *_strdup( const char *strSource );_strdup、_wcsdup、_mbsdup | MSDN
ただしこの関数の戻り値はmalloc()により確保された領域のため、不要になった時点でfree()により解放する必要があります。
char *strncpy( char *strDest, const char *strSource, size_t count );strncpy、_strncpy_l、wcsncpy、_wcsncpy_l、_mbsncpy、_mbsncpy_l | MSDN
strDestの先頭count文字だけをstrSourceへコピーし、strDestを返します。
char *strchr( char *str, // 検索対象の文字列 int c // 検索する文字 );strchr、wcschr、_mbschr、_mbschr_l | MSDN
結果はマッチした文字を指すポインタで返されるため、その位置を知りたいならば対象の文字列のポインタから減算します。
char* s = "ABCABC"; int index = -1; char* ret = strchr(s, 'B'); if( ret != NULL) { index = (int)(ret - s); // 1 } char* ret1 = strchr(s, 'b'); // NULL char* ret2 = strchr(s, 'Z'); // NULL
char *_strnset( char *str, // 変換する文字 int c, // 設定する文字 size_t count // 設定する文字の数 );_strnset、_strnset_l、_wcsnset、_wcsnset_l、_mbsnset、_mbsnset_l | MSDN
文字列strの先頭count文字分を、cに置換します。
char string[15] = "This is a test";
_strnset( string, '*', 4 ); // "**** is a test"
int strcmp( const char *string1, const char *string2 );strcmp、wcscmp、_mbscmp | MSDN
"C"ロケールでは、ASCII文字セット内の順で比較されます。
戻り値 | string1とstring2の関係 |
---|---|
-1 (0より小さい値) | string1はstring2より小さい |
0 | string1はstring2と同一 |
1 (0より大きい値) | string1はstring2より大きい |
char str1[] = "a"; char str2[] = "b"; int r1 = strcmp(str1, str2); // -1 int r2 = strcmp(str2, str1); // 1 int r3 = strcmp(str1, str1); // 0 strcmp("AB", "BA"); // -1
文字列を数値に変換する関数 | Microsoft Learn
__int64 _strtoi64( const char *strSource, char **endptr, int base );_strtoi64, _wcstoi64, _strtoi64_l, _wcstoi64_l | Microsoft Learn
char *source = "20"; char *end; __int64 v1 = _strtoi64(source, &end, 10); // 20 __int64 v2 = _strtoi64(source, &end, 16); // 32
double strtod( const char *strSource, char **endptr );strtod, _strtod_l, wcstod, _wcstod_l | Microsoft Learn
char *source1 = "1.23ABC"; char *end1; double x1 = strtod(source1, &end1); bool s1 = (source1 == end1); // false // x1: 1.2300000000000000 // end1: ABC
数値としての解釈に失敗したことは、strSourceとendptrが等しいことで確認できます。それ以外の問題は、errnoで確認できます。
char *source2 = "a"; char *end2; double x2 = strtod(source2, &end2); bool s2 = (source2 == end2); // true // x2: 0.0000000000000000 // end2: a