您將行讀入line
,因此您應該將line
更改爲regexec()
。您還需要考慮行尾的換行符是否會影響模式。 (這是正確使用fgets()
,但請記住它使換行符結尾。)
你也應該做return -1;
(或任何其他值不爲0模256),而不是一個普通的return
沒有價值。另外,你應該檢查文件是否被打開;我不得不使用的替代名稱,因爲沒有這樣的文件我的機器上的/etc/rc.conf - MacOS X的
這個工作對我來說:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <regex.h>
#define tofind "[a-z A-Z] $"
int main(int argc, char **argv)
{
FILE *fp;
char line[1024];
int retval = 0;
regex_t re;
//this file has this line "DAEMONS=(sysklogd network sshd !netfs !crond)"
const char *filename = "/etc/rc.conf";
if (argc > 1)
filename = argv[1];
if (regcomp(&re, tofind, REG_EXTENDED) != 0)
{
fprintf(stderr, "Failed to compile regex '%s'\n", tofind);
return EXIT_FAILURE;
}
fp = fopen(filename, "r");
if (fp == 0)
{
fprintf(stderr, "Failed to open file %s (%d: %s)\n",
filename, errno, strerror(errno));
return EXIT_FAILURE;
}
while ((fgets(line, 1024, fp)) != NULL)
{
line[strlen(line)-1] = '\0';
if ((retval = regexec(&re, line, 0, NULL, 0)) == 0)
printf("<<%s>>\n", line);
}
return EXIT_SUCCESS;
}
如果您需要幫助編寫正則表達式而不是幫助編寫使用它們的C代碼,然後我們需要設計正則表達式來匹配你顯示的行。
^DAEMONS=([^)]*) *$
只要它如圖所示寫入,它就會匹配該行。如果你可以有「S
」和「=
」或「=
」和「(
」之間的空間,那麼你就需要適當的修改。我已經允許尾隨空白 - 人們往往馬虎,但是如果他們使用尾隨選項卡,那麼該行將不會被選中。
一旦你找到了行了,你必須把它分割成塊。你可能會選擇使用「捕捉」括號設施,或者乾脆用strchr()
找到開括號,然後一個合適的技術來分離守護進程的名字 - 我會避免strtok()
和可能使用strspn()
或strcspn()
找到的話。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <regex.h>
#define tofind "^DAEMONS=\\(([^)]*)\\)[ \t]*$"
int main(int argc, char **argv)
{
FILE *fp;
char line[1024];
int retval = 0;
regex_t re;
regmatch_t rm[2];
//this file has this line "DAEMONS=(sysklogd network sshd !netfs !crond)"
const char *filename = "/etc/rc.conf";
if (argc > 1)
filename = argv[1];
if (regcomp(&re, tofind, REG_EXTENDED) != 0)
{
fprintf(stderr, "Failed to compile regex '%s'\n", tofind);
return EXIT_FAILURE;
}
fp = fopen(filename, "r");
if (fp == 0)
{
fprintf(stderr, "Failed to open file %s (%d: %s)\n", filename, errno, strerror(errno));
return EXIT_FAILURE;
}
while ((fgets(line, 1024, fp)) != NULL)
{
line[strlen(line)-1] = '\0';
if ((retval = regexec(&re, line, 2, rm, 0)) == 0)
{
printf("<<%s>>\n", line);
printf("Line: <<%.*s>>\n", (int)(rm[0].rm_eo - rm[0].rm_so), line + rm[0].rm_so);
printf("Text: <<%.*s>>\n", (int)(rm[1].rm_eo - rm[1].rm_so), line + rm[1].rm_so);
char *src = line + rm[1].rm_so;
char *end = line + rm[1].rm_eo;
while (src < end)
{
size_t len = strcspn(src, " ");
if (src + len > end)
len = end - src;
printf("Name: <<%.*s>>\n", (int)len, src);
src += len;
src += strspn(src, " ");
}
}
}
return EXIT_SUCCESS;
}
一個很好的協議在那裏調試代碼的 - 但它不會帶你長,產生你要求的答案。我得到:
<<DAEMONS=(sysklogd network sshd !netfs !crond)>>
Line: <<DAEMONS=(sysklogd network sshd !netfs !crond)>>
Text: <<sysklogd network sshd !netfs !crond>>
Name: <<sysklogd>>
Name: <<network>>
Name: <<sshd>>
Name: <<!netfs>>
Name: <<!crond>>
請注意:當你想在正則表達式一個反斜槓,你必須寫在C源代碼的兩個反斜槓。
只是想補充一點,正則表達式'toFind'是有缺陷的。反正什麼都不會。 – 2010-09-04 18:23:29
@Jeff:你確定?如圖所示,RE找到一個單一的字母,後跟一個空白和行尾或兩個空白和行尾。解析/etc/rc.conf是否合理是一個問題 - 然而,RE會發現它想要查找的內容。 – 2010-09-04 18:36:05
不過,我沒有得到任何輸出? /etc/rc。conf內容是
bla bla bla DAEMONS=(sysklogd network sshd !netfs !crond) bla bla bla
– Face 2010-09-04 18:51:27