Linux講座にようこそ。このページは「C言語プログラミング入門 - 第14章.ライブラリ関数 - 文字列処理ライブラリ」です。

C言語プログラミング入門

14. ライブラリ関数(13/36) - 文字列処理ライブラリ(2/5)

14.16 文字列長の取得関数

14.16.1 strlen関数

strlen関数はヌル文字を含まない文字列の長さ(文字数)を取得します。

【表14-2-2】 strlen関数
形式#include <string.h>
size_t strlen(const char *str);
返り値文字列の長さを返します。文字列の最後のヌル文字を含みます。
引数
const char *str
長さを求めたい文字列を指定します。
使用法、
返り値の型はsize_tになっていますが、これは長さを表すための型名でヘッダファイルに定義してあります。通常はunsigned intですので整数値として取り扱います。

14.16.2 例題

入力した文字列の長さ(文字数)を表示します。

  1. #include <stdio.h>
  2. #include <string.h>
  3. #define BUFFSIZE    1024
  4.  
  5. int main(void)
  6. {
  7.     char    buff[BUFFSIZE];
  8.     char    ans;
  9.  
  10.     do
  11.     {
  12.         printf("メッセージを入力してください ==> ");
  13.         fgets(buff, BUFFSIZE, stdin);
  14.  
  15.         printf("長さは%d文字です。\n", strlen(buff) - 1);
  16.  
  17.         printf("再度入力しますか(y/n) ==> ");
  18.         scanf("%c%*c", &ans);
  19.     } while(ans == 'y' || ans == 'Y');
  20.  
  21.     return 0;
  22. }
$ ./ex14_2_1.prg
メッセージを入力してください ==> Hello World.
長さは12文字です。
再度入力しますか(y/n) ==> y
メッセージを入力してください ==> Bye Bye.
長さは8文字です。
再度入力しますか(y/n) ==> n
$
$ ./ex14_2_1.prg
メッセージを入力してください ==> こんにちは。
長さは18文字です。 ← 日本語文字列の場合は、正しい文字数ではありません
再度入力しますか(y/n) ==> n
$
2行目
strlen関数を使いますのでstring.hファイルを取り込みます。
15行目
strlen関数で入力メッセージの文字数を取得します。改行文字を含んだ文字数が返ってきますので1を減算した値を出力します。

14.17 文字列の比較関数

14.17.1 strcmp関数

strcmp関数は2つの文字列を比較し、結果を返り値で返します。

文字列の比較ですのでヌル文字が現れるまで1文字ずつ比較します。長さが異なる場合はヌル文字が現れた時点で比較を終了します。

【表14-2-3】 strcmp関数
形式#include <string.h>
int strcmp(const char *str1, const char *str2);
返り値比較結果を次のような値で返します。
  • str1がstr2よりも小さい場合は負の整数値を返します。
  • str1とstr2が等しい場合は0を返します。
  • str1がstr2よりも大きい場合は正の整数値を返します。
引数
const char *str1
比較する文字列を指定します。
const char *str2
比較する文字列を指定します。

14.17.2 strncmp関数

strncmp関数は2つの文字列を比較し、結果を返り値で返します。strcmp関数との相違は第3引数で比較する文字数を指定できることです。

【表14-2-4】 strncmp関数
形式#include <string.h>
int strncmp(const char *s1, const char *s2, size_t n);
返り値strcmp関数と同じです。
引数
const char *str1
比較する文字列を指定します。
const char *str2
比較する文字列を指定します。
size_t n
比較する文字数を指定します。

14.17.3 memcmp関数

memcmp関数は2つのメモリ領域を比較し、結果を返り値で返します。比較する領域は文字列でなくても構いません。

【表14-2-5】 memcmp関数
形式#include <string.h>
int memcmp(const void *mem1, const void *mem2, size_t n);
返り値strcmp関数と同じです。
引数
const void *mem1
比較する領域を指定します。
const void *mem2
比較する領域を指定します。
size_t n
比較する文字数(バイト数)を指定します。

14.17.4 例題

文字列を2つ入力してそれが等しいか否かを表示します。

  1. #include <stdio.h>
  2. #include <string.h>
  3. #define BUFFSIZE    1024
  4.  
  5. int main(void)
  6. {
  7.     char    pass1[BUFFSIZE];
  8.     char    pass2[BUFFSIZE];
  9.  
  10.     printf("パスワードを入力してください ==> ");
  11.     fgets(pass1, BUFFSIZE, stdin);
  12.     printf("再度同じパスワードを入力してください ==> ");
  13.     fgets(pass2, BUFFSIZE, stdin);
  14.  
  15.     if (strcmp(pass1, pass2) == 0)
  16.     {
  17.         printf("OKです。\n");
  18.     }
  19.     else
  20.     {
  21.         printf("NGです。パスワードが異なります。\n");
  22.     }
  23.  
  24.     return 0;
  25. }
$ ./ex14_2_2.prg
パスワードを入力してください ==> hogehogepass
再度同じパスワードを入力してください ==> hogehogepass
OKです。
$
$ ./ex14_2_2.prg
パスワードを入力してください ==> hogehogepass
再度同じパスワードを入力してください ==> HOGEHOGEPASS
NGです。パスワードが異なります。
$
15行目
strcmp関数でpass1とpass2の文字列を比較します。返り値が0の場合は二つの文字列が等しいことになります。

14.18 文字列のコピー関数

14.18.1 strcpy関数

strcpy関数は終端のヌル文字を含めて文字列をコピーします。使用する場合は次の点に注意してください。

  • コピー元とコピー先の文字列は重なっていないこと。
  • コピー先の文字列はコピー元の文字列が全部入るだけの大きさがあること。
【表14-2-6】 strcpy関数
形式#include <string.h>
char *strcpy(char *dest, const char *src);
返り値コピー先の文字列destへのポインタを返します。
引数
char *dest
コピー先の文字列を指定します。
const char *src
コピー元の文字列を指定します。

14.18.2 strncpy関数

strncpy関数は終端のヌル文字を含めて文字列をコピーします。strcpy関数との相違は第3引数でコピーする文字数を指定できることです。使用上の注意点もstrcpy関数と同じですが、さらに次の点にも注意してください。

  • コピー元の先頭から第3引数で指定したコピーする文字数の間にヌル文字がない場合は、コピー先の文字列は終端のヌル文字がない状態になります。
  • コピー元の文字列が第3引数で指定したコピーする文字数よりも小さい(短い)場合は、コピー先の文字列の残りの部分はヌル文字を埋め込みます。
【表14-2-7】 関数
形式#include <string.h>
char *strncpy(char *dest, const char *src, size_t n);
返り値strcpy関数と同じです。
引数
char *dest
コピー先の文字列を指定します。
const char *src
コピー元の文字列を指定します。
size_t n
コピーする文字数を指定します。

14.18.3 memcpy関数

memcpy関数はメモリ領域を第3引数で指定したバイト数分コピーします。コピー元とコピー先が重なっている場合はmemmove関数を使用してください。

【表14-2-8】 memcpy関数
形式#include <string.h>
void *memcpy(void *dest, const void *src, size_t n);
返り値コピー先の領域destへのポインタを返します。
引数
void *dest
コピー先の領域を指定します。
const void *src
コピー元の領域を指定します。
size_t n
コピーするバイト数を指定します。

14.18.4 例題

任意の数のメッセージを入力して、入力し終わったら番号を付けて表示します。メッセージの入力は「end」が入力されるか、10個入力されるまで続きます。なお、malloc関数はメモリ領域を動的に確保する関数で、free関数は確保した領域を解放する関数です。これらについては後ほど説明します。

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #define BUFF_SIZE    1024
  5. #define MESSAGE_MAX  10
  6.  
  7. int main(void)
  8. {
  9.     char    buff[BUFF_SIZE];
  10.     char    *message_buff[MESSAGE_MAX];        /* メッセージ格納領域の配列 */
  11.     char    *message_ptr;                      /* メッセージ格納領域ポインタ */
  12.     int     message_idx;
  13.     int     num;
  14.  
  15.  
  16.     for(message_idx = 0; message_idx < MESSAGE_MAX; ++message_idx)
  17.     {
  18.         printf("メッセージを入力してください ==> ");
  19.         fgets(buff, BUFF_SIZE, stdin);
  20.         if(strncmp(buff, "end", 3))
  21.         {
  22.             /* メッセージを格納するための領域を確保 */
  23.             message_ptr = (char *)malloc(strlen(buff) + 1);
  24.             /* メッセージ格納領域に入力したメッセージをコピー */
  25.             strcpy(message_ptr, buff);
  26.             /* メッセージ格納領域の配列にメッセージ格納領域のアドレスを設定 */
  27.             *(message_buff + message_idx) = message_ptr;
  28.         }
  29.         else
  30.         {
  31.             break;
  32.         }
  33.     }
  34.  
  35.     printf("\n入力したメッセージに番号を付加して表示します。\n");
  36.     for(num = 0; num < message_idx; ++num)
  37.     {
  38.         printf("%.3d : %s", num + 1, *(message_buff + num));
  39.  
  40.         /* メッセージ格納領域を解放 */
  41.         free(*(message_buff + num));
  42.     }
  43.  
  44.     return 0;
  45. }
$ ./ex14_2_3.prg
メッセージを入力してください ==> Hi.
メッセージを入力してください ==> Hello!
メッセージを入力してください ==> Bye.
メッセージを入力してください ==> Bye bye.
メッセージを入力してください ==> end

入力したメッセージに番号を付加して表示します。
001 : Hi.
002 : Hello!
003 : Bye.
004 : Bye bye.
$
10行目
入力したメッセージを格納するポインタの配列を宣言します。ここにメッセージ(char型の配列)の先頭アドレスを格納します。
20行目
入力メッセージが「end」かをチェックします。
25行目
メッセージ格納領域に入力したメッセージをコピーします。