これregcompとregexecのマニュアルページ「使用されていないすべての構造要素には -1 値が含まれます」を意味します。
しかし、最後の一致の後に値をチェックするロジックではrm_so
そうではありません。 0に等しい:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <regex.h>
#define MATCH_CNT 4
void print_matches(regmatch_t matches[])
{
printf("Regexec successful.\n");
int i = 0;
for(; i < MATCH_CNT; i++)
{
//########### HERE'S THE RUB ####################
if(matches[i].rm_so != -1)
{
printf("Match %i; Beginning:\t%i\n", i, matches[i].rm_so);
printf("Match %i; End:\t\t%i\n", i, matches[i].rm_eo);
}
}
}
int main(int argc, char *argv[])
{
if(argc != 3)
fprintf(stderr, "retester <pattern> <string>\n");
char *pat = argv[1];
char *str = argv[2];
regex_t compreg;
memset(&compreg, 0, sizeof(regex_t));
regmatch_t matches[MATCH_CNT];
memset(&matches, 0, MATCH_CNT*sizeof(regmatch_t));
int matchcnt = -1;
char *errbuff;
printf("Trying to match with extended regex...\n");
int compret = -2;
//set REG_EXTENDED flag
if((compret = regcomp(&compreg, pat, REG_EXTENDED)) == 0)
{
printf("Compiling successful.\n");
int execret = -2;
if((execret = regexec(&compreg, str, matchcnt, matches, 0)) == 0)
{
print_matches(matches);
}
else if(execret != 0)
{
printf("Regexec failed.\n");
size_t errbuffsz = regerror(execret, &compreg, 0, 0);
errbuff = malloc(errbuffsz);
memset(errbuff, '\0', errbuffsz);
regerror(execret, &compreg, errbuff, errbuffsz);
fprintf(stderr, "Regexec error: %s\n", errbuff);
}
}
else
{
printf("Compiling failed.\n");
size_t errbuffsz = regerror(compret, &compreg, 0, 0);
errbuff = malloc(errbuffsz);
memset(errbuff, '\0', errbuffsz);
regerror(compret, &compreg, errbuff, errbuffsz);
fprintf(stderr, "Regexec error: %s", errbuff);
}
free(errbuff);
errbuff = NULL;
regfree(&compreg);
return 0;
}
これは上記の出力です。パターンの私の理解は、一致するグループが1つしかないということです。文書によると、これは2つのパディングregmatch_t
要素を表示する必要があることを意味します。最初の要素は文字列全体を含み、2番目の要素は一致するグループを含みます。
[chb]$ gcc -g -o foo foo.c
[chb]$ ./foo "^ROOM\s{1}NAME:\s{1}([[:alpha:]]{6})" "ROOM NAME: BriCol"
Trying to match with extended regex...
Compiling successful.
Regexec successful.
Match 0; Beginning: 0
Match 0; End: 17
Match 1; Beginning: 11
Match 1; End: 17
Match 2; Beginning: 0
Match 2; End: 0
Match 3; Beginning: 0
Match 3; End: 0
私はコマンド内のロジックが何らかの形で影響を受けたmemset
と考えながら、配列のゼロ化をコメントアウトしました。regexec
ベストアンサー1
未使用の配列要素を-1で埋めるには、regexec
まずそこにいくつがあるかを知らせる必要があります。この行をmatchcnt
次に変更してください。MATCH_CNT
if((execret = regexec(&compreg, str, matchcnt, matches, 0)) == 0)
だからそれは
if((execret = regexec(&compreg, str, MATCH_CNT, matches, 0)) == 0)
int
(そして以前に欠けていたものを追加するとcompret = -2;
)プログラムは期待どおりに機能します。
$ ./549805 "^ROOM\s{1}NAME:\s{1}([[:alpha:]]{6})" "ROOM NAME: BriCol"
Trying to match with extended regex...
Compiling successful.
Regexec successful.
Match 0; Beginning: 0
Match 0; End: 17
Match 1; Beginning: 11
Match 1; End: 17
$
また、未定義の値で呼び出すことを防ぐには(初期化されていない場合)errbuff
に初期化する必要があります。これにより、戻り値を確認してください - 割り当てNULL
free()
errbuff
malloc()
できる失敗する。