C400

113. 文字列を置き換える strchg 関数

文字列を検索するのであれば、ご存知のように strstr 関数によって簡単に検索することができるが、
文字列を検索して別の文字列に置換えたいという場面はよくあるはずなのだが、
探索文字列の長さと置換え文字列の長さが異なる場合は、そう容易ではない。
挿入作業が発生するからである。
これをスマートにパフォーマンスよく行う関数: strchg を紹介しよう。
strchg 関数は Web でも紹介されているものがあるが
ここでは任意の長さの文字列にも対応しているものである。

【 サンプル TESTCHG 】
0001.00 #include <stdio.h>                                               
0002.00 #include <stdlib.h>                                              
0003.00 #include <string.h>                                              
0004.00                                                                  
0005.00 #define TRUE         0                                           
0006.00 #define FALSE       -1                                           
0007.00                                                                  
0008.00 void strchg(char *buf, const char *str1, const char *str2);      
0009.00 void main(void){                                                 
0010.00   char str[128];                                                 
0011.00                                                                  
0012.00   printf("** TESTCHG:  文字列の変換 **\n");                      
0013.00   getchar();                                                     
0014.00                                                                  
0015.00   strcpy(str, "facabcxbadd");                                    
0016.00   printf("[%d] str = [%s]\n", __LINE__, str);                    
0017.00   getchar();                                                     
0018.00   printf("abc--> <123> \n");                                     
0019.00   strchg(str, "abc", " <123> ");                                 
0020.00   printf("[%d] str = [%s]\n", __LINE__, str);                    
0021.00   getchar();                                                    
0022.00 }                                                               
0023.00 /*********************************************************/     
0024.00 void strchg(char *buf, const char *str1, const char *str2)      
0025.00 /*********************************************************/     
0026.00 {                                                               
0027.00   char* tmp, *p;                                                
0028.00   long  tmplen;                                                 
0029.00                                                                 
0030.00   while((p = strstr(buf, str1)) != NULL){/* while */            
0031.00     /*  見つからなくなるまで繰り返す                            
0032.00              p は旧文字列の先頭を指している  */                 
0033.00     *p = '\0'; /*  元の文字列を旧文字列の直前で区切って  */     
0034.00     p += strlen(str1);  /*  ポインタを旧文字列の次の文字へ  */  
0035.00     tmplen = strlen(p) + 1;                                     
0036.00     tmp = (char*)malloc(tmplen);                                
0037.00     strcpy(tmp, p);             /*  旧文字列から後を保存  */    
0038.00     strcat(buf, str2);  /*  新文字列をその後につなぎ  */        
0039.00     strcat(buf, tmp);   /*  さらに残りをつなぐ  */              
0040.00     free(tmp);                                                  
0041.00   }/*while */                                                   
0042.00 }                                                 
【解説】

このプログラムは文字列「facabcxbadd」の「abc」の3文字の部分列を
「 <123> 」という 7文字の文字列に置換える例を示している。
下記は実行結果である。