1

私はCの初心者で、この問題に数週間取り組んでいますが、私と同僚は解決策を理解できません。

問題のパート 1: ほとんどの Linux ディストリビューションに含まれている標準の C regex lib (regex.h) を使用しています。オンラインの多くの例と同様に、次のような一致関数を使用します

int match(const char *string, char *pattern) {
int    status;
regex_t    re;

if (regcomp(&re, pattern, REG_EXTENDED) != 0) {
    char    buffer[100];
    regerror(status, &re, buffer, 100);
    printf("regcomp() failed with '%s'\n", buffer);
    return(0);      /* Report error. */
}
status = regexec(&re, string, (size_t) 0, NULL, 0);
regfree(&re);
if (status != 0) {
    char    buffer[100];
    regerror(status, &re, buffer, 100);
    printf("regcomp() failed with '%s'\n", buffer);
    return(0);      /* Report error. */
}
printf("match: %s<\n",string);
return(1); 
}

次に、入力に対してチェックする正規表現を含むメイン関数があります (この場合は値 [1] でシミュレートしました)。この場合、値の 2 番目のエントリに対してのみ一致する必要があり、残りは 0 を返す必要があります。

int main() {
 int i = 0;
 char* values[16] = {"ADCICT.A100311.ANTRAG","ADCICT.A100311.ANTRAG.NR","ADDB2P.K004111.PLANxUEB","ADDB2Q.K004111.PLANxUEB","ADDB2P.K004111.PRODxUEB**",
 "ADDB2Q.K004111.PRODxUEB**","ADDB2P.K004111.SQLCODE","ADDB2Q.K004111.SQLCODE","ADDB2P.K004111.VORP#UEB","ADDB2Q.K004111.VORP#UEB",
 "ADEDVT.A347709.DDIO.*.PGM%COB**","AD000T.K001800.CICS.**","A9VIST.K001804.INFOS","ABC4","ABC5"}; 

 for ( i = 0; values[i] != NULL; i++ ) {
    char *theRegex = (char *) malloc(100);
    memset(theRegex, 0x00, 100);
    theRegex = values[i];
    printf("regexV=%x<", theRegex);
    transformRegex(&theRegex);
    printf("regexN=%s< ", theRegex);
    int reti = match(values[1], theRegex);
    printf("reti=%i\n", reti);
    fflush(stdout);
    //free(theRegex);
 }
}

transformRegex は char* を受け取り、最初に ^ を追加し、最後に $ を追加するだけです。

int transformRegex(char **regexS){
    char tmpStr[strlen(*regexS)+3];
    memset(tmpStr, 0x00, strlen(*regexS)+3);
    memcpy(tmpStr, "^", 1);
    memcpy(&tmpStr[1], *regexS, strlen(*regexS));
    strcat(tmpStr,  "$");
    *regexS = tmpStr;
    return 0;
}

実際、transformRegex 関数はもっと多くのことを行うはずでしたが、この問題の解決策を見つけることができなかったので、できるだけ多くのコードを削除する必要がありました。解決できないため、今では本当に、本当に疲れ果てています。 .

このプログラムを (gdb を使用して) 実行すると、次のようになります。

regexV=4010dc<regexN=^ADCICT.A100311.ANTRAG$< match: ADCICT.A100311.ANTRAG.NR<
reti=1
regexV=4010f2<regexN=^ADCICT.A100311.ANTRAG.NR$< match: ADCICT.A100311.ANTRAG.NR<
reti=1
regexV=40110b<regexN=^ADDB2P.K004111.PLANxUEB$< regcomp() failed with 'No match'
  [...]
reti=0
regexV=401207<regexN=^A9VIST.K001804.INFOS$< regcomp() failed with 'No match'
reti=0
regexV=40121c<regexN=^ABC4$< match: ADCICT.A100311.ANTRAG.NR<
reti=1
regexV=401221<regexN=^ABC5$< match: ADCICT.A100311.ANTRAG.NR<
reti=1

最後の 2 つのことはどのように一致するのでしょうか? 最初のものは言うまでもなく...

問題 2: この問題は以前からよく気になっていたのですが、自然に消えていったようです。この行を取り出すだけなら

printf("regexV=%x<", theRegex);

出力の最初の行は

regexN= Üÿÿ< regcomp() failed with 'No match'
reti=0

これは神の名において何ですか?printf ステートメントは、このようなコードにどのように影響しますか?

問題 3: 通常、割り当てたメモリを解放したいと考えています。正規表現を割り当てたので、ループの最後に解放したい

free(theRegex)

しかし、そうするとどうなるか見てみましょう:

regexV=4010ec<regexN=^ADCICT.A100311.ANTRAG$< match: ADCICT.A100311.ANTRAG.NR<
reti=1
*** glibc detected *** /home/itgsandbox/KK/a.out: double free or corruption (out): 0x00007fffffffdb70 ***
 [...]
Program received signal SIGABRT, Aborted.
0x00007ffff7ab2945 in raise () from /lib64/libc.so.6

私は本当に機知に富んでいます (C を始めたばかりなのであまり意味がありません) が、これらの問題は非常に巧妙な人が取り組んでいるようです。私を助けてください、私はあなたを信頼しています、Stackoverflow!

4

1 に答える 1