我必须开发一个简单的解析器,以读取文本的“块”
例如:

/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 .}

09-10 23:16