我有一个很大的.xml文件,需要从中提取特定的位。
我需要拉出的东西被两侧的子字符串封装。
我需要将输出写入文件。

我正在寻找开始子,然后从那里寻找结束子,然后将其复制并放在fprintf上。
我将起始指针设置为最后一个结束指针的位置,并且它将继续搜索,直到遇到sigsegv。

我不知道如何在我正在搜索的子字符串的最后一次出现之前停止循环,然后再运行到sigsegv中。

我遇到的一个有趣的问题是,如果我输出到stdout,它会打印所有我想拉出的东西,然后分解。
如果我想将其写入文件,它不会写相同的东西,但是会在完成之前崩溃,并在此过程中丢失最后37行输出。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {

    FILE *fp;
    fp = fopen("C:/Users/entin/Desktop/IHP/Auswerte_Marko/TEMP/20190605204730250_S210D_PQ41701_TM2_TV2_MARK21Single_21Single.ega_rslt", "r");

    FILE *fw;
    fw = fopen("C:/Users/entin/Desktop/IHP/Auswerte_Marko/TEMP/t1.xml", "w");

    int f_length;
    fseek(fp, 0, SEEK_END);
    f_length = ftell(fp);
    char file[f_length + 1];
    rewind(fp);
    fread(file, f_length, 1, fp);
    file[f_length] = 0;



    const char *SPattern = "<MeasData "; // start of substring
    const char *EPattern = "</MeasData>"; // end of substring
    char *start, *end;
    char *target = NULL;

    if (start = strstr(file, SPattern)) { // search for start substring
        start += strlen(SPattern);
        if (end = strstr(start, EPattern)) { // search for end substring
            target = (char *) malloc(end - start + 1);
            memcpy(target, start, end - start); // copying content between start and end pointers
            target[end - start] = '\0';

            start = end; // setting new start to old end
        }
    }

    if (target) fprintf(stdout, "%s%s%s\n", SPattern, target, EPattern); // assembling everything back together

    free(target);


    //while (end <= EOF) { // repeating till end of file is reached
    while (end != NULL && *end != 0){ //EDIT from comments
        char *target = NULL;
        if (start = strstr(start, SPattern)) { // startig search from last end pointer
            start += strlen(SPattern);
            if (end = strstr(start, EPattern)) {
                target = (char *) malloc(end - start + 1);
                memcpy(target, start, end - start);
                target[end - start] = '\0';

                start = end;
            }
        }

        if (target) fprintf(stdout, "%s%s%s\n", SPattern, target, EPattern);

        free(target);
    }

    fclose(fp);
    fclose(fw);
    getchar();
    return 0;
}


这些是文件:

Input File

Output to stdout that I want in a file

Output that I get when I write to a file

(仅输出的最后一行很重要)

最佳答案

您不应选择end,而应选择start

while (end != NULL && *end != 0){ //EDIT from comments
    char *target = NULL;
    if (start = strstr(start, SPattern)) { // startig search from last end pointer
        start += strlen(SPattern);
        if (end = strstr(start, EPattern)) {
            target = (char *) malloc(end - start + 1);
            memcpy(target, start, end - start);
            target[end - start] = '\0';

            start = end;
        }
    }

    if (target) fprintf(stdout, "%s%s%s\n", SPattern, target, EPattern);

    free(target);
}


如果找到最后一个元素并搜索下一个元素,则start将是NULL,并且您将不会输入if块。
在这种情况下,您无需更改end并再次调用strstr,但现在使用start == NULL

据我所记得,不需要strstr来验证有效的指针。

在您的循环中,只有找到开始模式但没有结束模式时,end才会成为NULL。对于有效的XML文件,这不太可能发生。

07-28 11:52