我必须开发一个简单的解析器,以读取文本的“块”
例如:
/TEST
{. text .}
/TEST_DATA
{. infs .}
并且,我需要阅读标签内部的信息。
和...具有此信息的文件...具有很多标签,具有相同的性能
例如:
/TEST
{. text .}
/TEST_DATA
{. infs .}
/LBL1
{. text .}
/LBL1_DATA
{. infs .}
/LBL2
{. text .}
/LBL2_DATA
{. infs .}
/LBL3
{. text .}
/LBL3_DATA
{. infs .}
我需要阅读specif标签块,例如:
parseFile(“ FileName.txt”,LBL1)
函数,为我返回块内部的文本:LBL1和LBL1_DATA
或者,为我返回LBL1和LBL1_DATA的内容
我不知道,我该怎么做:xxx
我需要帮助; x
谢谢。
最佳答案
假设数据是一行,这是一个非常简单的代码示例。
您显然需要对其进行测试,测试和测试。查看您的行为,修复可能的错误以及我忘记做的事情(现在这对您来说是一项工作),新的实现也是如此。
int main(void)
{
const char *key = "TEST";
const char *filename = "file";
char *val = get(filename, key);
if(val) {
printf("%s\n", val); // {. text .}
free(val); // don't to forget!
} else {
printf("'%s' was not found.\n", key);
}
}
char*
get(const char *filename, const char *key) {
char *line = NULL, *pline = NULL, *buf = NULL, *pbuf, *tbuf;
size_t size = -1, ssearch = strlen(key), i = 0, bufsize = 256;
int open = 0;
FILE *fp = fopen(filename, "r");
if(fp == NULL) {
fprintf(stderr, "Cannot read '%s' file.\n", filename);
exit(EXIT_FAILURE);
}
while(getline(&line, &size, fp) != -1) {
if(open == 0 && *line == '/' &&
strncmp(line + 1, key, ssearch) == 0 && isspace(((unsigned char)*(line + ssearch + 1)))) {
open = 1;
continue;
}
if(open) {
pline = line;
while(isspace((unsigned char) *pline)) ++ pline; /* strip white-spaces [\r\n\t\v ] */
if(*pline == '{') {
if((buf = malloc(bufsize)) == NULL) {
fprintf(stderr, "NO MEMORY!");
exit(EXIT_FAILURE);
}
++pline; /* strip '{' */
pbuf = buf;
while(1) {
if(*pline == '\0') {
fprintf(stderr, "EOF but '{' was not closed.");
exit(EXIT_FAILURE);
}
/* etc.. */
if(*pline == '}') break;
if((i + size + 1) >= bufsize) {
if((tbuf = realloc(buf, bufsize + size + 1)) == NULL) {
if(buf) free(buf);
fprintf(stderr, "No MEMORY!\n");
exit(EXIT_FAILURE);
}
buf = tbuf;
}
*pbuf ++= *pline++,
i ++;
}
*pbuf ++= '\0';
if(pline != NULL)
free(line);
fclose(fp);
return buf;
} else {
fprintf(stderr, "expected '{' but '%c' was found.\n", *pline);
exit(EXIT_FAILURE);
}
}
line = NULL;
size = -1;
}
if(line != NULL)
free(line);
fclose(fp);
return NULL;
}
更新:编写了更简单的代码。
#define EXPECTEDSYMBOL(w, f) \
fprintf(stderr, "expected '%c' but '%c' was found.\n", w, f); \
exit(EXIT_FAILURE)
char* get2(const char *filename, const char *key) {
char *line = NULL, *buf = NULL, *pline;
size_t size = -1, ssearch = strlen(key);
int open = 0;
FILE *fp = fopen(filename, "r");
if(fp == NULL) {
fprintf(stderr, "Cannot read '%s' file.\n", filename);
exit(EXIT_FAILURE);
}
while(getline(&line, &size, fp) != -1) {
if(open == 0 && *line == '/' &&
strncmp(line + 1, key, ssearch) == 0 && isspace(((unsigned char)*(line + ssearch + 1)))) {
open = 1;
continue;
}
if(open) {
pline = line;
while(isspace((unsigned char) *pline)) ++ pline;
if(*pline != '{') {
EXPECTEDSYMBOL('{', *pline);
}
if(strchr(pline, '}') == NULL) {
EXPECTEDSYMBOL('}', *(pline + strlen(pline) - 1));
}
buf = pline;
break;
}
line = NULL;
}
fclose(fp);
return buf;
}
希望对您有所帮助。
编辑#2:我再次阅读了您的问题,并看到您也需要以下键。
尝试这个:
void
get(const char *filename, const char *key, char buf[][512]) {
char *line = NULL;
size_t size = -1, ssearch = strlen(key);
int open = 0;
FILE *fp = fopen(filename, "r");
if(fp == NULL) {
fprintf(stderr, "Cannot read '%s' file.\n", filename);
exit(EXIT_FAILURE);
}
while(getline(&line, &size, fp) != -1) {
if(open == 0 && *line == '/' &&
strncmp(line + 1, key, ssearch) == 0 && isspace(((unsigned char)*(line + ssearch + 1)))) {
open = 1;
continue;
}
if(open == 1) {
strcpy(buf[0], line);
++ open;
continue;
}
if((open + 1) == 3) {
getline(&line, &size, fp);
strcpy(buf[1], line);
break;
}
}
fclose(fp);
}
接着:
const char *key = "TEST"; // /TEST
const char *filename = "config";
char buf[2][512] = { { 0 } };
get(filename, key, buf);
printf("%s\n", buf[0]); // {. text . }
printf("%s\n", buf[1]); // {. infs .}