C400

143. 不思議なstrchrによるスキャン

strchr も文字をスキャンして探す関数として知られている。
まずは次のプログラムを見て頂きたい。

[ TESTSCAN ]

ソースはこちらから

0001.00 #include                                                       
0002.00 #include                                                      
0003.00 #include                                                      
0004.00                                                                         
0005.00 #define TRUE         0                                                  
0006.00 #define FALSE       -1                                                  
0007.00                                                                         
0008.00 void main(void){                                                        
0009.00    char buff[128], *ptr;                                                
0010.00    int  i, pos;                                                         
0011.00                                                                         
0012.00    printf("** TESTSCAN :  スキャンのテスト **n");                      
0013.00    getchar();                                                           
0014.00    strcpy(buff, " 晋吾 ");                                              
0015.00    printf("[%d] buff=[%s]n", __LINE__, buff);                          
0016.00    for(i = 0; i<strlen(buff); i++){/*for-loop*/                         
0017.00      printf("[%d] buff[%d]= 0x%02xn", __LINE__, i, buff[i]);           
0018.00    }/*for-loop*/                                                        
0019.00    printf("[%d] \-mark is 0x%02xn", __LINE__, '\');                    
0020.00    ptr = strchr(buff, '\');                                             
0021.00    if(ptr != NULL){/* 見つかった */                                     
0022.00      pos = (int)(ptr - buff);                                           
0023.00      printf("[%d] found \-mark at %d in [%s]n", __LINE__, pos, buff);  
0024.00    }/* 見つかった */                                           
0025.00    else{/*not found*/                                          
0026.00      printf("[%d] not found \-mark in [%s]n", __LINE__, buff);
0027.00    }/*not found*/                                              
0028.00    getchar();                                                  
0029.00    exit(0);                                                    
0030.00 }       


                                                        

[コンパイル]

CRTBNDC PGM(TEST.COM/TESTSCAN) SRCFILE(MYSRCLIB/QCSRC2) AUT(*ALL

[解説]

つまりこの関数は
文字列: 晋吾 = 0x0e4bb247f60f の中から文字 \=0xb2 を関数 strptr によって
検索するものである。
読者は見つかると考えるかそれとも見つからないと思われるか?

答えは環境によって変わるである。
通常の環境で実行してもると

   ** TESTSCAN :  スキャンのテスト **      
 >                                         
   [15] buff=[ 晋吾 ]                      
   [17] buff[0]= 0x0e                      
   [17] buff[1]= 0x4b                      
   [17] buff[2]= 0xb2                      
   [17] buff[3]= 0x47                      
   [17] buff[4]= 0xf6                      
   [17] buff[5]= 0x0f                      
   [19] \-mark is 0xb2                     
   [26] not found \-mark in [ 晋吾 ]       

しかし QSECOFRで実行してみると

  ** TESTSCAN :  スキャンのテスト **    
>                                       
  [15] buff=[ 晋吾 ]                    
  [17] buff[0]= 0x0e                    
  [17] buff[1]= 0x4b                    
  [17] buff[2]= 0xb2                    
  [17] buff[3]= 0x47                    
  [17] buff[4]= 0xf6                    
  [17] buff[5]= 0x0f                    
  [19] \-mark is 0xb2                   
  [23] found \-mark at 2 in [ 晋吾 ]    

これはどういうことだろうか?
_

先ほどは

   [26] not found \-mark in [ 晋吾 ] 

ということで見つからなかったのに今度は

  [23] found \-mark at 2 in [ 晋吾 ] 

ということで見つかったということになる。
この違いは何かと言うと ロケール(=QLOCALE) である。

DSPSYSVAL で一般ユーザーを見てみると

 ロケール . . . . . . . . . . . . . . . . . :   *SYSVAL 

とは DSPSYAVAL QLOCALE で見てみると

 /QSYS.LIB/JA_5035.LOCALE

のように登録されている。
しかし DSPSYSVAL QSECOFR で見てみると

ロケール . . . . . . . . . . . . . . . . . :   *NONE

である。
つまりロケールの登録のあるときは
0x0e~0x0f のシフト文字のあいだは漢字として解釈されているので
strchr は漢字中の文字列は検索対象とはしないが
QSECOFRはようにロケールが*NONEである場合は
漢字は考慮されずらすべての文字列が検索の対象となる。

このことは strchr の解説を見てみれば「QLOCALEの影響を受ける」とだけしか
書かれていないがその意味はこういうことである。