这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;
}
这是上面的输出。我对该模式的理解是它只有一个匹配组。根据文档,这意味着我应该看到两个填充regmatch_t
元素:第一个包含整个字符串,第二个包含匹配的组。
[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
如果你想regexec
用-1填充未使用的数组元素,你需要首先告诉它有多少个。在这一行中替换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()
它的返回值——分配能失败。