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

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

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

14.24 その他の関数

14.24.1 strerror関数

strerror関数はエラー番号に対応する説明文を取得します。通常、エラー番号はライブラリ関数でエラーが発生した時に、外部変数errnoに設定される値を指定します。

【表14-2-21】 strerror関数
形式#include <string.h>
char *strerror(int errno);
返り値エラー番号に対応する説明文の先頭アドレスを返します。エラー番号に対応する説明文が無い場合は「Unknown error nnn」という説明文を返します。
引数
int errno
エラー番号を指定します。

14.24.2 strpbrk関数

strpbrk関数は指定された文字の組み合わせ(文字セット)から成る文字列を検索します。

【表14-2-22】 strpbrk関数
形式#include <string.h>
char *strpbrk(const char *str, const char *keyset);
返り値文字セットに含まれる文字のどれかに一致した文字のアドレスを返します。一致する文字が見つからなかった場合はNULLを返します。
引数
const char *str
検索対象の文字列を指定します。
const char *keyset
文字セットを指定します。

14.24.3 例題

テキストファイル中の英字(a〜z、A〜Z、半角スペース)の部分だけを抽出して表示します。(機能的にはstrspn関数の例題と同じです)なお、入力ファイル(./DATA/ex14_2_6.dat)が入力出来なかった場合は、標準エラー出力にメッセージを出力します。

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <errno.h>           /* errno定義 */
  4. #define LINE_MAX    1024
  5.  
  6. int main(void)
  7. {
  8.     char *SubStr(char *Str, int Start, int Length);
  9.  
  10.     FILE    *fp;
  11.     char    in_file[] = "./DATA/ex14_2_6.dat";
  12.     char    line[LINE_MAX];
  13.     char    key_set[] ="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ";
  14.     char    *p_line;               /* キーセット検索開始位置 */
  15.     char    *p_pos;                /* キーセット検索結果位置 */
  16.     int     len;
  17.  
  18.     if((fp = fopen(in_file, "r")) != NULL)
  19.     {
  20.         /* EOFでない間、繰り返す */
  21.         while(fgets(line, LINE_MAX, fp) != NULL)
  22.         {
  23.             /* 行の最後まで */
  24.             for(p_line = line; *p_line != '\0'; )
  25.             {
  26.                 /* 英字とスペースのチェック */
  27.                 if((p_pos = strpbrk(p_line, key_set)) != NULL)
  28.                 {
  29.                     /* 英字とスペースから成る文字列が有った。文字数を取得 */
  30.                     len = strspn(p_pos, key_set);
  31.                     /* 英字とスペースから成る文字列を表示 */
  32.                     printf("%s\t", SubStr(p_pos, 0, len));
  33.                     p_line = p_pos + len;
  34.                 }
  35.                 else
  36.                 {
  37.                     break;
  38.                 }
  39.             }
  40.  
  41.             if(p_line != line)
  42.             {
  43.                 /* 英字とスペースから成る文字列が有った */
  44.                 printf("\n");
  45.             }
  46.         }
  47.         fclose(fp);
  48.     }
  49.     else
  50.     {
  51.         fprintf(stderr, "%s\n", strerror(errno));
  52.     }
  53.  
  54.     return 0;
  55. }
  56.  
  57. /* 文字列中の指定された位置の文字列を取り出す */
  58. char *SubStr(char *pStr, int pStart, int pLength)
  59. {
  60.     static char buff[LINE_MAX];
  61.     char       *p_buff = buff;
  62.  
  63.     for(pStr += pStart; *pStr != '\0' && pLength > 0; --pLength)
  64.     {
  65.         *(p_buff++) = *(pStr++);
  66.     }
  67.     *p_buff = '\0';
  68.  
  69.     return buff;
  70. }
$ ./ex14_2_9.prg
Merry Husky     A
Kuma Mix
Hana Shiba      AB
ken Mix
Taro Bull       A
$
$ mv ./DATA/ex14_2_6.dat ./DATA/ex14_2_6.txt ← ファイル名ex14_2_6.datをex14_2_6.txtに変更します
$ ./ex14_2_9.prg
No such file or directory
$
3行目
外部変数errnoを使用するため、errno.hファイルを取り込みます。
27行目
入力した文字列中から、英字とスペース(文字セット)から成る文字列を検索します。返り値がNULLの場合は、検索失敗です。
30行目
英字とスペース(文字セット)から成る文字列の文字数を取得します。
51行目
入力ファイルが入力できなかった場合に、標準エラー出力にエラーメッセージを出力します。

14.24.4 memmove関数

memmove関数はメモリ領域を第3引数で指定したバイト数分コピーします。コピー元とコピー先が重なっていてもかまいません。(重なっていない場合はmemcpy関数を使った方が良いでしょう)

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

14.24.5 memset関数

memset関数はメモリ領域を指定した値(1バイト長)で埋め込みます。

【表14-2-24】 memset関数
形式#include <string.h>
void *memset(void *dest, int c, size_t n);
返り値メモリ領域destの先頭アドレスを返します。
引数
void *dest
メモリ領域を指定します。
int c
埋め込む値(1バイト長)を指定します。
size_t n
埋め込む長さをバイト単位で指定します。

14.24.6 例題

指定した高さの三角形を表示します。

  1. #include <stdio.h>
  2. #include <string.h>
  3. #define LINE_MAX    1024
  4.  
  5. int main(void)
  6. {
  7.     char    buff[LINE_MAX];
  8.     int     height;
  9.     int     sp_num;            /* スペースの数 */
  10.     int     ast_num;           /* *の数 */
  11.  
  12.     printf("三角形の高さを入力してください ==> ");
  13.     scanf("%d", &height);
  14.  
  15.     sp_num = height - 1;
  16.     ast_num = 1;
  17.  
  18.     /* 高さ分だけ繰り返す */
  19.     for( ; height > 0; --height)
  20.     {
  21.         /* 1行分の文字列を作る */
  22.         memset(buff, ' ', sp_num);
  23.         memset(buff + sp_num, '*', ast_num);
  24.         *(buff + sp_num + ast_num)  = '\0';
  25.         /* 1行表示 */
  26.         printf("%s\n", buff);
  27.  
  28.         --sp_num;
  29.         ast_num += 2;
  30.     }
  31.  
  32.     return 0;
  33. }
$ ./ex14_2_10.prg
三角形の高さを入力してください ==> 8
       *
      ***
     *****
    *******
   *********
  ***********
 *************
***************
$
22行目
buffの先頭からsp_num個のスペースを埋め込みます。
23行目
上記で埋め込んだスペースの次からast_num個の「*」を埋め込みます。