【C】初めてのC言語（20. 文字列を扱う標準関数）

# はじめに

* これまでの学習に続いて、今回は文字列操作の関数について学んだ結果をまとめてみました。


# 学習環境

* 今回は[paiza.io](https://paiza.io/ja/projects/new)のC言語のエディタを使いました。

# strlen関数

* 文字列の長さ（バイト数）を取得する関数です。
* 文字列（配列）の先頭から`\0`までの長さが返されます。
* `strlen`関数の戻り値は`size_t`型ですが、ここでは`int`型にキャストして受け取っています。

```c:Main.c
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
    const char str[100] = "Test";
    int length = (int)strlen(str);

    printf("文字列の長さ：%d\n", length);
    return 0;#include <stdio.h>

int main(int argc, char *argv[])
{
    char buff[256];
    gets(buff);  // 256バイトを超えても終端文字が現れないとバッファオーバーフローが発生する！
    
    printf("入力値：%s\n", buff);
    return 0;
}
}
```

```text:実行結果
文字列の長さ：4
```

# strcmp関数

* 2つの文字列を比較するための関数です。
* 引数で指定した2つの文字列が等しければ`0`が返されます。
  * 戻り値が0であるかをチェックすれば、文字列が同一であるかをチェックできます。
* [memcmp関数](https://qiita.com/nkojima/items/13c8d942f282beb3c212#memcmp%E9%96%A2%E6%95%B0)と似ていますが、`memcmp`関数はバイト数を指定して比較するのに対して、`strcmp`関数は「`\0`が出現するまでの範囲」を比較します。

```c:Main.c
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
    char str1[10] = "Test";
    char str2[10] = "Test2";
    
    str2[4] = '\0';  // 「2」を終端文字に置き換える
    
    if (strcmp(str1,str2)==0) {
        printf("「%s」と「%s」は同じです。", str1, str2);
    } else {
        printf("「%s」と「%s」は異なります。",str1, str2);
    }
    return 0;
}
```

```text:実行結果
「Test」と「Test」は同じです。
```

# strcpy関数

* 文字列をまるごとコピーする関数です。
* コピー先には、十分なメモリ領域が割り当てられていることが前提となります。

```c:Main.c
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
    char* src = "Test";
    char dest[100];
    
    strcpy(dest, src);
    
    printf("destは「%s」です。", dest);
    return 0;
}
```

```text:実行結果
destは「Test」です。
```

# strcat関数

* 2つの文字列を連結させる関数です。
* 第1引数の末尾にある終端文字「\0」を削除して、第2引数の文字列をコピーして連結させます。

```c:Main.c
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
    char* src = ",world!";
    char dest[100] = "Hello";
    
    strcat(dest, src);
    
    printf("destは「%s」です。", dest);
    return 0;
}
```

```text:実行結果
destは「Hello,world!」です。
```

# sprintf関数

* 書式を指定して文字列に書き込む関数です。
* `printf`は書式を指定して文字列を標準出力しましたが、`sprintf`関数は書式を指定してメモリ領域に書き込みます。

```c:Main.c
#include <stdio.h>

int main(void){
    char str[100];
    sprintf(str, "%sの所持金は%d円です。", "nkojima", 12611);
    
    printf("%s\n", str);
    return 0;
}
```

```text:実行結果
nkojimaの所持金は12611円です。
```

# scanf関数

* 書式を指定してキーボードからの入力を受け取ります。
* `scanf`関数では、キーボードの入力値を書き込んで欲しい「メモリ領域のアドレス」を渡す必要があるため、`money`のアドレスである`&money`を渡しています。
  * char型の配列である`name`については、`&name[0]`と同義なのでそのまま`name`を引数として渡しています。

```c:Main.c
#include <stdio.h>
int main(void){
    char name[100];
    int money;
    
    printf("名前と所持金を半角スペース区切りで入力してください。\n");
    scanf("%s %d", name, &money);
    
    printf("%sの所持金は%d円です。\n", name, money);
    return 0;
}
```

```text:入力値
nkojima 12611
```

```text:実行結果
名前と所持金を半角スペース区切りで入力してください。
nkojimaの所持金は12611円です。
```


# 補足：これまでの学習の歩み

* [【C】初めてのC言語（1. Hello world）](https://qiita.com/nkojima/items/518c1a4ec06861d74b3c)
* [【C】初めてのC言語（2. 四則演算とフォーマット指定子）](https://qiita.com/nkojima/items/36ea93b7296ce9e8a55b)
* [【C】初めてのC言語（3. ポインタ）](https://qiita.com/nkojima/items/825bb9f931016faccd68)
* [【C】初めてのC言語（4. 構造体）](https://qiita.com/nkojima/items/40a1101f2f6f5800bc2d)
* [【C】初めてのC言語（5. 関数）](https://qiita.com/nkojima/items/1fa3317c04f25fe24276)
* [【C】初めてのC言語（6. 配列）](https://qiita.com/nkojima/items/eda3ff6675b47e7ab5f0)
* [【C】初めてのC言語（7. for文）](https://qiita.com/nkojima/items/a5659098f7e5275a96ec)
* [【C】初めてのC言語（8. 2次元配列）](https://qiita.com/nkojima/items/f5eb25a4f8d1725faa89)
* [【C】初めてのC言語（9. 関数のプロトタイプ宣言）](https://qiita.com/nkojima/items/57318d74bdfa670bf72e)
* [【C】初めてのC言語（10. 構造体配列）](https://qiita.com/nkojima/items/75530a3ca63924a14397)
* [【C】初めてのC言語（11. ヘッダファイル）](https://qiita.com/nkojima/items/a10cd943ed66e0cea7fd)
* [【C】初めてのC言語（12. 3つのからくり構文＋ポインタ演算）](https://qiita.com/nkojima/items/83cb40ec01cd6a6e6a87)
* [【C】初めてのC言語（13. メモリを扱う標準関数）](https://qiita.com/nkojima/items/13c8d942f282beb3c212)
* [【C】初めてのC言語（14. ヒープの利用）](https://qiita.com/nkojima/items/837557cc86ce9697611a)
* [【C】初めてのC言語（15. sizeofの注意点）](https://qiita.com/nkojima/items/6c9a3ba04c6348219578)
* [【C】初めてのC言語（16. 文字列の基本）](https://qiita.com/nkojima/items/d87ce0cb15dd1a26f21a)
* [【C】初めてのC言語（17. 文字列リテラル）](https://qiita.com/nkojima/items/527ef37d84cf9b201dc5)
* [【C】初めてのC言語（18. 文字列の受け渡し）](https://qiita.com/nkojima/items/a07ac9a9bb3b41296f1e)
* [【C】初めてのC言語（19. 文字列とバッファオーバーフロー）](https://qiita.com/nkojima/items/4d9cec9e686aee41eec2)

# 参考URL

* [スッキリわかるC言語入門 第2版](https://www.amazon.co.jp/dp/4295012785/)
  * p.417～p.426