RPG でのフィールド内容の比較 (memicmp() と memcmp())

今まで、RPG の中から C の関数を使用することができることを「RPG で C ランタイム関数を使用する」や「RPG から CL コマンドの実行 (system() 関数を使って)」などで使用例を見てきましたが、今回はフィールドの内容の比較方法を見てみたいと思います。


memicmp() という関数を使用すると、2つのバッファ(まぁ要するにプログラム内のフィールド)間のByte to Byte の比較を行うことができます。"Byte to Byte"と言いましたが、内容はたいていの場合は文字でしょう。アルファベットの大文字/小文字は区別しないようにしています。

結果を表示させるのに「RPG からジョブログへの書き込み (Qp0zLprintf() の利用)」で使った方法を流用しています。

使い方は簡単で、引数として比較対象とする 2つのフィールドの個々の内容と、比較するバイト数の 3つを指定して呼び出すだけです。

比較するバイト数を指定しなかった場合は、後の方のフィールドの内容の長さを取っています。

     H BNDDIR('QC2LE')  DFTACTGRP(*NO)                                                              
      *                                                                                             
     D COMPSTR         PR                                                                           
     D  val1                         10a                                                            
     D  val2                         10a                                                            
     D  len                           3U 0                                                          
      *                                                                                             
     D COMPSTR         PI                                                                           
     D  val1                         10a                                                            
     D  val2                         10a                                                            
     D  len                           3U 0                                                          
      *                                                                                             
     D memicmp         PR            10i 0 extProc('__memicmp')                                     
     D  pVal1                          *   VALUE                                                    
     D  pVal2                          *   VALUE                                                    
     D  nLen                         10u 0 VALUE                                                    
      *                                                                                             
     D msgr            C                   CONST('%s is %s, right?')                                
     D msgw            C                   CONST('%s is not %s, right?')                            
     D str1            S             10a                                                            
     D str2            S             10a                                                            
      *                                                                                             
     D prtjoblog       PR            10i 0 extProc('Qp0zLprintf')                                   
     D  prtstr                         *   VALUE OPTIONS(*STRING)                                   
     D  ps1                            *   VALUE OPTIONS(*STRING:*NOPASS)                           
     D  ps2                            *   VALUE OPTIONS(*STRING:*NOPASS)                           
     D  ps3                            *   VALUE OPTIONS(*STRING:*NOPASS)                           
     D  ps4                            *   VALUE OPTIONS(*STRING:*NOPASS)                           
     D  ps5                            *   VALUE OPTIONS(*STRING:*NOPASS)                           
     D  ps6                            *   VALUE OPTIONS(*STRING:*NOPASS)                           
     D  ps7                            *   VALUE OPTIONS(*STRING:*NOPASS)                           
      /Free                                                                                         
                                                                                                    
              if (len > 0);                                                                         
              else;                                                                                 
                len = %len(%trimR(val2));                                                           
              endif;                                                                                
                                                                                                    
              str1 = %trimR(%subst(val1:1:len));                                                    
              str2 = %trimR(%subst(val2:1:len));                                                    
                                                                                                    
              if (memicmp(%addr(str1):%addr(str2):len) = 0);                                        
                  prtjoblog(msgr+x'25':%trimR(str1):%trimR(str2));                                  
              else;                                                                                 
                  prtjoblog(msgw+x'25':%trimR(str1):%trimR(str2));                                  
              endif;                                                                                
                                                                                                    
               *inLR = *on ;                                                                        
               return;                                                                              
                                                                                                    
      /End-Free

比較するバイト数の指定のない場合、双方のフィールドの内容のどちらでも長いほうを取る、というロジックのものも作ってみました。

     H BNDDIR('QC2LE')  DFTACTGRP(*NO)                                                              
      *                                                                                             
     D COMPSTRL        PR                                                                           
     D  val1                         10a                                                            
     D  val2                         10a                                                            
     D  len                           3U 0                                                          
      *                                                                                             
     D COMPSTRL        PI                                                                           
     D  val1                         10a                                                            
     D  val2                         10a                                                            
     D  len                           3U 0                                                          
      *                                                                                             
     D memicmp         PR            10i 0 extProc('__memicmp')                                     
     D  pVal1                          *   VALUE                                                    
     D  pVal2                          *   VALUE                                                    
     D  nLen                         10u 0 VALUE                                                    
      *                                                                                             
     D msgr            C                   CONST('%s is %s, right?')                                
     D msgw            C                   CONST('%s is not %s, right?')                            
     D str1            S             10a                                                            
     D str2            S             10a                                                            
      *                                                                                             
     D prtjoblog       PR            10i 0 extProc('Qp0zLprintf')                                   
     D  prtstr                         *   VALUE OPTIONS(*STRING)                                   
     D  ps1                            *   VALUE OPTIONS(*STRING:*NOPASS)                           
     D  ps2                            *   VALUE OPTIONS(*STRING:*NOPASS)                           
     D  ps3                            *   VALUE OPTIONS(*STRING:*NOPASS)                           
     D  ps4                            *   VALUE OPTIONS(*STRING:*NOPASS)                           
     D  ps5                            *   VALUE OPTIONS(*STRING:*NOPASS)                           
     D  ps6                            *   VALUE OPTIONS(*STRING:*NOPASS)                           
     D  ps7                            *   VALUE OPTIONS(*STRING:*NOPASS)                           
      /Free                                                                                         
                                                                                                    
              if (len > 0);                                                                         
              else;                                                                                 
                len = %len(%trimR(val2));                                                           
                if (len < %len(%trimR(val1)));                                                      
                  len = %len(%trimR(val1));                                                         
                endif;                                                                              
              endif;                                                                                
                                                                                                    
              str1 = %trimR(%subst(val1:1:len));                                                    
              str2 = %trimR(%subst(val2:1:len));                                                    
                                                                                                    
              if (memicmp(%addr(str1):%addr(str2):len) = 0);                                        
                  prtjoblog(msgr+x'25':%trimR(str1):%trimR(str2));                                  
              else;                                                                                 
                  prtjoblog(msgw+x'25':%trimR(str1):%trimR(str2));                                  
              endif;                                                                                
                                                                                                    
               *inLR = *on ;                                                                        
               return;                                                                              
                                                                                                    
      /End-Free

結果は、わかりますよね?! 大文字と小文字を区別していないことも確認できます。

最後の 2つの実行例はバイト数を指定しない場合のサンプルプログラム両者の挙動の違いを確認しています。

DBCS文字も当然比較することは可能です。

下の最初の実行例で言えば、x'0E' を 1バイト、DBCS文字一つで 2バイトで計 3バイトを比較しているわけです。終わりの x'0F' がないためにメッセージが化けてしまっていますが、これは同じものと判定されています。

大文字と小文字を区別させたい場合は memcmp() を使用します。

     H BNDDIR('QC2LE')  DFTACTGRP(*NO)                                                              
      *                                                                                             
     D COMPSTRCS       PR                                                                           
     D  val1                         10a                                                            
     D  val2                         10a                                                            
     D  len                           3U 0                                                          
      *                                                                                             
     D COMPSTRCS       PI                                                                           
     D  val1                         10a                                                            
     D  val2                         10a                                                            
     D  len                           3U 0                                                          
      *                                                                                             
     D memcmp          PR            10i 0 extProc('__memcmp')                                      
     D  pVal1                          *   VALUE                                                    
     D  pVal2                          *   VALUE                                                    
     D  nLen                         10u 0 VALUE                                                    
      *                                                                                             
     D msgr            C                   CONST('%s is %s, right?')                                
     D msgw            C                   CONST('%s is not %s, right?')                            
     D str1            S             10a                                                            
     D str2            S             10a                                                            
      *                                                                                             
     D prtjoblog       PR            10i 0 extProc('Qp0zLprintf')                                   
     D  prtstr                         *   VALUE OPTIONS(*STRING)                                   
     D  ps1                            *   VALUE OPTIONS(*STRING:*NOPASS)                           
     D  ps2                            *   VALUE OPTIONS(*STRING:*NOPASS)                           
     D  ps3                            *   VALUE OPTIONS(*STRING:*NOPASS)                           
     D  ps4                            *   VALUE OPTIONS(*STRING:*NOPASS)                           
     D  ps5                            *   VALUE OPTIONS(*STRING:*NOPASS)                           
     D  ps6                            *   VALUE OPTIONS(*STRING:*NOPASS)                           
     D  ps7                            *   VALUE OPTIONS(*STRING:*NOPASS)                           
      /Free                                                                                         
                    if (len > 0);                                                                   
                    else;                                                                           
                      len = %len(%trimR(val2));                                                     
                    endif;                                                                          
                                                                                                    
                    str1 = %trimR(%subst(val1:1:len));                                              
                    str2 = %trimR(%subst(val2:1:len));                                              
                                                                                                    
                    if (memcmp(%addr(str1):%addr(str2):len) = 0);                                   
                        prtjoblog(msgr+x'25':%trimR(str1):%trimR(str2));                            
                    else;                                                                           
                        prtjoblog(msgw+x'25':%trimR(str1):%trimR(str2));                            
                    endif;                                                                          
                                                                                                    
                     *inLR = *on ;                                                                  
                     return;                                                                        
                                                                                                    
      /End-Free

ちゃんと区別しているのがわかりますね。

[Top Pageに戻る]

Ads by TOK2