我正在尝试从文件中提取数字。我有限制,我只需要使用open()
,read()
和close()
。
我已成功读取数据并保存在缓冲区中。不,我需要将它与RE匹配。 我正在使用RE = ^ [0-9] *
这是我的代码
char buffer[1024] = { NULL };
int count = 0;
int fRead;
fRead = open("file.in", O_RDONLY);
read(fRead, buffer, sizeof(buffer));
printf("\nFile Opened %s, %lu", buffer, sizeof(buffer));
/* Compile regular expression */
regex_t re;
int reti = regcomp(&re, "^[1-9]*", 0);
if (reti) {
fprintf(stderr, "Could not compile regex\n");
exit(1);
}
/* Execute regular expression */
reti = regexec(&re, buffer, 0, NULL, 0);
if (!reti) {
printf("\nMatch: %d", reti);
} else if (reti == REG_NOMATCH) {
puts("No match");
} else {
char msgbuf[100];
regerror(reti, &re, msgbuf, sizeof(msgbuf));
fprintf(stderr, "Regex match failed: %s\n", msgbuf);
exit(1);
}
close(fRead);
现在问题是我想计算并显示我在文件中找到的数字。
例如,我的文件可能包含文本some thing 2 to 3 makes 5
,在这种情况下,我的输出必须是
OUTPUT:
2,3,5
count = 3
答案 0 :(得分:3)
看看man page for regexec。正如您使用的那样,regexec的返回值为0表示成功或正错误代码。但是,regexec的其他参数是如何获得有关匹配的更多信息。
为方便起见,这里是regexec的定义:
int regexec(const regex_t *preg, const char *string, size_t nmatch,
regmatch_t pmatch[], int eflags);
pmatch参数是函数在找到它们时匹配的位置,而nmatch参数告诉函数pmatch参数有多少元素,因此它不会溢出。这类似于其他语言“匹配”函数,其中pmatch的第一个索引将具有完整的正则表达式匹配,而以下索引将具有子组匹配。这意味着您需要使用子组匹配来获取字符串中的数字,然后您需要循环遍历字符串以查找后续子组匹配。
首先,实例化一个regmatch_t堆栈变量来保存结果。这只需要大小为2,因此您可以将完整匹配存储在0索引中,并将子组匹配存储在1索引中。您还需要更改正则表达式,以便它匹配整个字符串,直到它到达一个数字。我们将它传递给regexec函数及其nmatch的大小。
每次找到匹配项时,您都需要向前移动字符串的开头,以便下次调用regexec时,您将获得下一个数字而不是同一个。< / p>
首先更新正则表达式字符串。
/* if we use .* in the regex it will be greedy and match the last number, not the first.
We need to use a + instead of a * for the number so we know there is at least 1. */
int reti = regcomp(&re, "[^0-9]*([0-9]+)", REG_EXTENDED);
然后循环找到所有匹配。
/* regmatch_t is defined in regex.h */
regmatch_t matches[2];
int start;
int end;
while (1) {
reti = regexec(&re, buffer, 2, matches, 0);
/* rm_so is the start index of the match */
start = matches[1].rm_so;
/* rm_eo is the end index of the match */
end = matches[1].rm_eo;
/* break if we didn't find a match */
if (reti) break;
/* print the substring that contains the match */
printf("%.*s, ", (end - start), (buffer + start));
/* increment the count of matches */
count = count + 1;
/* This is really important!
Move the start of the string forward so we don't keep matching the same number! */
buffer = buffer + end;
}
/* print the count */
printf("count = %d", count);