这是“如何解析配置文件”的问题。 基本上我有一个文本文件(/ etc / myconfig)具有所有类型的设置。我需要读取该文件并搜索字符串:
wants_return=yes
一旦找到该字符串,我需要解析它并返回等号后的任何字符串。 我尝试过使用fgets和strtok的组合,但我在这里感到困惑。 在任何情况下,任何人都知道可以执行此功能的功能吗?
感谢代码。
感谢
答案 0 :(得分:2)
这有效:(注意:我不确定fgets是否应该在返回的字符串中包含换行符;如果不包含,则可以放弃检查)
#include <stdio.h>
const unsigned MAXLINE=9999;
char const* FCFG="/etc/myconfig";
char const* findkey="wants_return=";
char * skip_ws(char *line)
{
return line+strspn(line," \t");
}
char * findval(char *line,char const* prefix,int prelen)
{
char *p;
p=skip_ws(line);
if (strncmp(p,prefix,prelen)==0)
return p+prelen;
else
return NULL;
}
char *findval_slow(char *line,char const* prefix)
{
return findval(line,prefix,strlen(prefix));
}
int main() {
FILE *fcfg;
char line[MAXLINE];
char *p,*pend;
int findlen;
findlen=strlen(findkey);
fcfg=fopen(FCFG,"r");
while (p=fgets(line,MAXLINE,fcfg)) {
printf("Looking at %s\n",p);
if (p=findval(line,findkey,findlen)) {
pend=p+strlen(p)-1; /* check last char for newline terminator */
if (*pend=='\n') *pend=0;
printf("Found %s\n",p); /* process/parse the value */
}
}
return 0;
}
答案 1 :(得分:1)
以下是使用strtok
的简短示例:
const int linelen = 256;
char line[linelen];
FILE* fp = fopen(argv[1], "r");
if (fp == NULL) {
perror("Error opening file");
} else {
while (! feof(fp)) {
if (fgets(line, linelen , fp)) {
const char* name = strtok(line, "= \r\n");
const char* value = strtok(NULL, "= \r\n");
printf("%s => %s\n", name, value);
}
}
fclose (fp);
}
注意,你需要对它进行一些额外的错误检查,但是这可以解析我扔给它的文件。
答案 2 :(得分:0)
从您的评论中,您似乎已经使用 fgets 从文本文件中获取了相应的行并将其加载到字符缓冲区中。您可以使用 strtok 来解析行中的标记。
如果使用字符串 buffer 作为第一个参数运行它,它将从该字符串返回第一个标记。如果在第一个参数设置为 NULL 的情况下运行相同的命令,它将从相同的原始字符串返回后续标记。
如何检索多个令牌的快速示例:
#include <stdio.h>
#include <string.h>
int main() {
char buffer[17]="wants_return=yes";
char* tok;
tok = strtok(buffer, "=");
printf("%s\n", tok); /* tok points to "wants_return" */
tok = strtok(NULL, "=");
printf("%s\n", tok); /* tok points to "yes" */
return 0;
}
对于第二次 strtok 调用,您可以将"="
替换为""
,将所有内容都返回到字符串的末尾,而不是在下一个等号处中断
答案 3 :(得分:-1)
使用POSIX shell,我会使用类似的东西:
answer=`egrep 'wants_config[ ]*=' /etc/myconfig | sed 's/^.*=[ ]*//'`
当然,如果您正在寻找使用C STDIO库的答案,那么您真的需要查看STDIO文档。