[C言語 標準ライブラリ] string.hの使い方

※本ブログでは、商品・サービスのリンク先にプロモーションを含みます。

スポンサーリンク

文字列処理およびメモリ転送処理をするための関数が宣言および定義されています。

スポンサーリンク

マクロ

NULL

実装で定義されたNULLポインタ定数です。

size_t

sizeof演算子の結果である符号なし整数型です。

コピー関数

void *memcpy(void *s1, const void *s2, size_t n)

s2が指すオブジェクトからn文字を、s1が指すオブジェクトにコピーします。
コピー元とコピー先が重なる場合の動作は未定義です。
s1の値が返されます。

使用例:

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

int main(void)
{
    char src[50] = "Hello, world!";
    char dest[50];

    memcpy(dest, src, strlen(src)+1);  // +1は\0を含めるようにするため
    printf("コピーした文字列は、%s\n", dest);

    return 0;
}

実行結果:

コピーした文字列は、Hello, world!

void *memmove(void *s1, const void *s2, size_t n)

s2が指すオブジェクトの先頭n文字をs1が指すオブジェクトにコピーします。
コピー元とコピー先が重なる場合も正しくコピーされます。
s1の値が返されます。

使用例:

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

int main(void)
{
    char str[50] = "Hello, world!";

    memmove(str+6, str+5, strlen(str)-4);
    printf("移動した文字列は、%s\n", str);

    return 0;
}

実行結果:

移動した文字列は、Hello,, world!

void *strcpy(char *s1, const char *s2)

s2が指す文字列を、s1が指す配列にコピーします。
コピー元とコピー先が重なる場合の動作は未定義です。
s1の値が返されます。

使用例:

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

int main(void)
{
    char src[50] = "Hello, world!";
    char dest[50];

    strcpy(dest, src);
    printf("コピーした文字列は、%s\n", dest);

    return 0;
}

実行結果:

コピーした文字列は、Hello, world!

void *strncpy(char *s1, const char *s2, size_t n)

s2が指す文字列を、s1が指す配列にコピーします。
s2の長さがn以上の場合はn文字までをコピーし、nより短い場合は残りをNULL文字で埋めます。
コピー元とコピー先が重なる場合の動作は未定義です。
s1の値が返されます。

使用例:

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

int main(void)
{
    char src[50] = "Hello, world!";
    char dest[50];

    strncpy(dest, src, 5);
    dest[5] = '\0';  // 終端に\0を設定する
    printf("コピーした文字列は、%s\n", dest);

    return 0;
}

実行結果:

コピーした文字列は、Hello

連結関数

void *strcat(char *s1, const char *s2)

s2が指す文字列を、s1が指す配列の末尾にコピーします。
コピー元とコピー先が重なる場合の動作は未定義です。
s1の値が返されます。

使用例:

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

int main(void)
{
    char dest[50] = "Hello";
    char src[50]  = ", world!";

    strcat(dest, src);
    printf("連結された文字列は、%s\n", dest);

    return 0;
}

実行結果:

連結された文字列は、Hello, world!

void *strncat(char *s1, const char *s2, size_t n)

s2が指す文字列を、s1が指す配列の末尾ににコピーします。
s2の長さがnより長い場合は切り捨てられます。
コピー元とコピー先が重なる場合の動作は未定義です。
s1の値が返されます。

使用例:

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

int main(void)
{
    char dest[50] = "Hello";
    char src[50]  = ", world!";

    strncat(dest, src, 3);  // 3文字だけ追加する
    printf("連結された文字列は、%s\n", dest);

    return 0;
}

実行結果:

連結された文字列は、Hello, w

比較関数

int memcmp(const void *s1, const void *s2, size_t n)

s1が指すオブジェクトの先頭n文字と、s2が指すオブジェクトの先頭n文字をunsigned char型の値として先頭から順に比較します。
等しければ0が返され、s1がs2より大きければ正の整数値が返され、s1がs2より小さければ負の整数値が返されます。

使用例:

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

int main(void)
{
    char buff1[20] = "Hello, world!";
    char buff2[20] = "Hello, world!";

    int n = memcmp(buff1, buff2, sizeof(buff1));

    if(n == 0){
        printf("buff1とbuff2は同じデータ。\n");
    }else{
        printf("buff1とbuff2は異なるデータ。\n");
    }

    return 0;
}

実行結果:

buff1とbuff2は同じデータ。

int strcmp(const char *s1, const char *s2)

s1が指す文字列とs2が指す文字列の大小関係を1文字ずつ比較します。
等しければ0が返され、s1がs2より大きければ正の整数値が返され、s1がs2より小さければ負の整数値が返されます。

使用例:

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

int main(void)
{
    char str1[] = "Hello, world!";
    char str2[] = "Hello, World!";

    int result = strcmp(str1, str2);

    if(result == 0){
        printf("str1とstr2は同じ文字列です。\n");
    }else if(result < 0){
        printf("str1はstr2より小さい文字列です。\n");
    }else{
        printf("str1はstr2より大きい文字列です。\n");
    }

    return 0;
}

実行結果:

str1はstr2より大きい文字列です。

int strcoll(const char *s1, const char *s2)

s1が指す文字列とs2が指す文字列を比較します。
このとき、いずれの文字列も、ロケールLC_COLLATEカテゴリに基づいて解釈されます。
両方の文字列を現在のロケールに基づいて解釈したときに、等しければ0が返され、s1がs2より大きければ正の整数値が返され、s1がs2より小さければ負の整数値が返されます。

int strncmp(const char *s1, const char *s2, size_t n)

s1が指す文字の配列とs2が指す文字の配列の先頭n文字までの大小関係を1文字ずつ比較します。
等しければ0が返され、s1がs2より大きければ正の整数値が返され、s1がs2より小さければ負の整数値が返されます。

使用例:

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

int main(void)
{
    char str1[] = "Hello, World!";
    char str2[] = "Hello, everyone!";

    // 最初の7文字を比較
    int result = strncmp(str1, str2, 7);

    if(result == 0){
        printf("文字列の最初の7文字が等しい。\n");
    }else if (result < 0){
        printf("str1の最初の7文字がstr2より小さい。\n");
    }else{
        printf("str1の最初の7文字がstr2より大きい。\n");
    }

    return 0;
}

実行結果:

文字列の最初の7文字が等しい。

size_t strxfrm(char *s1, const char *s2, size_t n)

s2が指す文字列を変換し、s1が指す配列に格納します。
strcmp関数を二つの変換した文字列に適用した場合、正、0、負の値が返され、それは同じ二つの文字列をstrcoll関数に適用した結果と一致します。
終端を示すNULL文字を含めて、n個を超える文字をs1が指す配列に格納することはありません。
nが0である場合、s1はNULLポインタであっても構いません。
重なり合うオブジェクト間でコピーする場合、その動作は未定義です。
変換した結果の文字列(NULL文字は含まない)が返されます。
戻り値がn以上の場合は、s1が指す配列の内容は不定となります。

スポンサーリンク

探索関数

void *memchr(const void *s, int c, size_t n)

sが指すオブジェクトの先頭n文字(unsigned char型として解釈)の中でunsigned char型に変換したcの最初の出現を探索します。
探索した文字へのポインタが返されます。
ただし、見つからなかった場合は、NULLポインタが返されます。

使用例:

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

int main(void){
    char str[] = "Hello, World!";
    char ch = 'W';
    char *found_char = memchr(str, ch, strlen(str));

    if(found_char != NULL){
        printf("位置 %d に文字 %c が見つかりました。\n", found_char - str, ch);
    }else{
        printf("文字 %c が見つかりません。\n", ch);
    }

    return 0;
}

実行結果:

位置 7 に文字 W が見つかりました。

char *strchr(const char *s, int c)

s2が指す文字列の中に最も先頭側に出現する(char型に変換した)cを探索します。
cは文字列の終端を示すNULL文字でも構いません。
探索した文字へのポインタが返されます。
文字がなければNULLポインタが返されます。

使用例:

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

int main(void)
{
    char str[] = "Hello, World!";
    char ch = 'W';
    char *found_char = strchr(str, ch);

    if(found_char != NULL){
        printf("位置 %d に文字 %c が見つかりました。\n", found_char - str, ch);
    }else{
        printf("文字 %c が見つかりません。\n", ch);
    }

    return 0;
}

実行結果:

位置 7 に文字 W が見つかりました。

size_t strcspn(const char *s1, const char *s2)

s1の文字列の中から、s2の指定した文字集合のいずれかの文字が最初に現れる位置を見つけ、その位置までの長さを返します。
指定した文字集合の文字が見つからない場合、元の文字列の長さを返します。

使用例:

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

int main(void)
{
    char str1[] = "Hello, World!";
    char str2[] = ",!";

    size_t len = strcspn(str1, str2);

    printf("%sの文字を含まない初期セグメントの長さは%dです。\n", str2, len);

    return 0;
}

実行結果:

,!の文字を含まない初期セグメントの長さは5です。

char *strpbrk(const char *s1, const char *s2)

s1が指す文字列の中で、s2が指す文字列中のいずれかの文字の最初の出現を探索し、その文字へのポインタが返されます。
いずれの文字も現れない場合は、NULLポインタが返されます。

使用例:

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

int main(void)
{
    char str1[] = "Hello, World!";
    char str2[] = ",!";

    char *found_char = strpbrk(str1, str2);

    if(found_char != NULL){
        printf("%sからの最初の文字が位置%dで見つかりました。\n", str2, found_char - str1);
    }else{
        printf("%sからの文字が見つかりません。\n", str2);
    }

    return 0;
}

実行結果:

,!からの最初の文字が位置5で見つかりました。

char *strrchr(const char *s, int c)

sが指す文字列の中に最も末尾側に出現する(char型に変換した)cを探索します。
cは文字列の終端を示すNULL文字でも構いません。
探索した文字へのポインタが返されます。
文字がなければNULLポインタが返されます。

使用例:

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

int main(void)
{
    char str[] = "Hello, World!";
    char ch = 'o';
    char *found_char = strrchr(str, ch);

    if(found_char != NULL){
        printf("文字 %c が最後から %d の位置に見つかりました。\n", ch, strlen(str) - (found_char - str));
    }else{
        printf("文字 %c が見つかりません。\n", ch);
    }

    return 0;
}

実行結果:

文字 o が最後から 5 の位置に見つかりました。

size_t strspn(const char *s1, const char *s2)

s2が指す文字列中の文字だけを含む、s1が指す文字列の先頭部分の最大の長さを求めます。
その先頭部分の長さが返されます。

使用例:

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

int main(void)
{
    char str1[] = "123456abc789";
    char str2[] = "1234567890";

    size_t len = strspn(str1, str2);

    printf("%sの文字だけを含む初期セグメントの長さは、%dです。\n", str2, len);

    return 0;
}

実行結果:

1234567890の文字だけを含む初期セグメントの長さは、6です。

char *strstr(const char *s1, const char *s2)

s1が指す文字列の中で最も先頭側に出現する、s2が指す文字列と同じ文字の並び(NULL文字は含まない)を探索します。
探索した文字の並びの先頭文字へのポインタが返されます。
見つからなかった場合は、NULLポインタが返されます。
s2が長さ0の文字列であればs1が返されます。

使用例:

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

int main(void)
{
    char haystack[] = "Hello, World!";
    char needle[] = "World";

    char *found_str = strstr(haystack, needle);

    if(found_str != NULL){
        printf("サブストリング %s が位置 %d に見つかりました。\n", needle, found_str - haystack);
    }else{
        printf("サブストリング %s が見つかりませんでした。\n", needle);
    }

    return 0;
}

実行結果:

サブストリング World が位置 7 に見つかりました。

char *strtok(char *s1, const char *s2)

s1が指す文字列を、s2が指す文字列の中のいずれかの文字で区切られる文字の並びへと一連の呼出しによって分割します。
最初の呼出しでは、第1実引数とs1を設定します。
2回目以降の呼出しでは、s1にはNULLポインタを、s2には文字列を区切るための文字の並びを設定します。
なお、s2は呼出しのたびに異なっても構いません。
区切られた文字の並びの最初の文字へのポインタが返されます。
存在しない場合は、NULLポインタが返されます。

使用例:

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

int main(void)
{
    char str[] = "Hello, World! How are you?";
    char delim[] = " ,?!";

    char *token = strtok(str, delim);

    while(token != NULL){
        printf("Token: %s\n", token);
        token = strtok(NULL, delim);
    }

    return 0;
}

実行結果:

Token: Hello
Token: World
Token: How
Token: are
Token: you

その他の関数

char *memset(void *s, int c, size_t n)

sが指すオブジェクトの先頭n文字に、unsigned char型に変換したcの値を代入します。
sの値が返されます。

使用例:

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

int main(void)
{
    char str[50] = "Hello, World!";

    printf("memset実行前:%s\n", str);

    memset(str + 7, '*', 5);

    printf("memset実行後:%s\n", str);

    return 0;
}

実行結果:

memset実行前:Hello, World!
memset実行後:Hello, *****!

char *strerror(int errnum)

エラー番号errnumをエラーメッセージ列に対応付けます。
文字列へのポインタが返されます。
その内容は、処理系定義です。
指される配列はプログラムで変更してはならないが、本関数を呼び出すたびに上書きされることがあります。

使用例:

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

int main(void)
{
    FILE *file;

    file = fopen("non_existent_file.txt", "r");

    if(file == NULL){
        printf("Error: %s\n", strerror(errno));
    }

    return 0;
}

このプログラムでは、存在しないファイルを開こうとしてエラーが発生します。fopen関数はエラーが発生するとNULLを返し、グローバル変数errnoにエラー番号を設定します。その後、このエラー番号をstrerror関数に渡して、対応するエラーメッセージを取得し、それを出力します。

実行結果:

Error: No such file or directory

※具体的なエラーメッセージはプラットフォームによって異なります。

size_t strlen(const char *s)

sが指す文字列の長さを計算します。
終端を示すNULL文字に先行する文字の個数が返されます。

使用例:

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

int main(void)
{
    char str[] = "Hello, World!";

    printf("文字列の長さは、%d\n", strlen(str));

    return 0;
}

実行結果:

文字列の長さは、13

スポンサーリンク
C言語

コメント