【问题标题】:How do I read a text file's contents and return a string between two strings I specify? [closed]如何读取文本文件的内容并返回我指定的两个字符串之间的字符串? [关闭]
【发布时间】:2017-01-01 06:54:03
【问题描述】:

这里是example.txt

##TITLE
My program
# 1
# 2
##

到目前为止,我有一个函数可以读取整个文件并在 char* 中返回其内容。

char *getTextBlock(const char *filename, char *textBlockLabel){
    char *fileContents;
    long fileSize;
    FILE *fp=   fopen(filename,"r");

    fseek(fp, 0, SEEK_END);
    fileSize=   ftell(fp);
    rewind(fp);

    fileContents=   malloc(fileSize * sizeof(char));
    fread(fileContents, sizeof(char), fileSize, fp);

    fclose(fp);
    return fileContents;
}

当我运行这个程序时,这个函数是getTextBlock("example.txt","##TITLE");

我想在example.txt 中获取并返回##TITLE## 之间的所有内容。

在这种情况下,这意味着:

My program
# 1
# 2

我该怎么做?

【问题讨论】:

  • How do I do this? --> 请展示您迄今为止的研究/调试工作。请先阅读How to Ask页面。
  • 由于"##TITLE" 不包括行尾,我希望输出从##TITLE 之后的行尾开始。所以输出将是"\nMy program\n# 1\n..."
  • 在你的函数中我没有看到第二个模式(“##”)
  • 您是否特别希望返回行(而不是单词或字符)?换句话说,如果该示例文件的第一个类似文件是##TITLE SomeText,那么"SomeText" 是否应该成为您输出的一部分?您对短语TextBlock 的使用表明您希望一次对线路进行操作。如果是这样,您最好将文件拆分为单行字符串数组,使您的信息单元成为“文本行”;此刻,它是“性格”。 (此外,您的 getTextBlock 函数可能应该采用第三个参数:类似于 textBlockEnd。)

标签: c


【解决方案1】:

事情是一旦你得到一个字符串中的文件内容你就可以做这件事

    char *begin,*end;
    begin= strstr( s, pattern) // ##TITLE
    char *op = NULL;
    if ( begin !=NULL )
    {
        begin += strlen( pattern);
        end = strstr( begin, pattern1); // ##
        if (end!=NULL )
        {
            op= malloc( end- begin+ 1 );
            if(op == NULL)
            { 
               printf("%s","ERROR in Allocation");
               // if you use in function return or show message
            }
            else
            {
               memcpy( op, begin, end- begin);
               op[end - begin] = '\0';
               //print op or what you want
            }
        }
    }
    else
    {
       // first pattern not found. return empty string or show message
    }

来自莫斯科的弗拉德的大部分帮助。 这是他的answer。从这个我几个月前使用它..并存储在我的机器中。现在我又用了。

代码说明

这段代码完全按照我们被要求执行任务时所做的事情

  • 因此,首先,我们试图从包含文件包含的所有内容的字符串中找出第一个“TITLE##”。

  • 如果我们没有找到它,那么程序将不打印任何内容,或者可能返回一个空字符串。

  • 如果第一个strstr 返回的不是NULL,那么我们找到了它。我们将再次开始搜索。但是我们从哪里开始呢?我们需要从第一个模式出现的末尾开始,否则我们会从TITLE## 本身找到##,这不是我们想要的。

  • 所以我们正确设置了指针,然后再次搜索第二个模式。

  • 如果找到,那么我们将分配一个大小为end-begin+1 的字符串,额外的空间1 用于保存\0 或字符串结尾标记。

  • 我们需要检查malloc的返回值是否成功。

注意:最好用NUL 终止字符串,我的代码假定了这一点。只需将\0 放在您收集文件所有内容的字符串末尾即可。

【讨论】:

    【解决方案2】:

    我的解决方案:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    char* getTextBlock(const char *filename, char *textBlockLabel){
        char *fileContents;
    
        FILE * pFile;
        long lSize;
        char * buffer;
        size_t result;
    
        pFile = fopen (filename , "r" );
        if (pFile==NULL) {
            fputs ("File error",stderr);
            return NULL;
        }
    
        // obtain file size:
        fseek (pFile , 0 , SEEK_END);
        lSize = ftell (pFile);
        rewind (pFile);
    
        // allocate memory to contain the whole file:
        buffer = (char*) malloc (sizeof(char)*lSize);
        if (buffer == NULL) {
            fputs ("Memory error",stderr);
            return NULL;
        }
    
        // copy the file into the buffer:
        result = fread (buffer,1,lSize,pFile);
        if (result != (unsigned long)lSize) {
            fputs ("Reading error",stderr);
            return NULL;
        }
    
        fileContents = strstr(buffer, textBlockLabel);
        if(fileContents!= NULL)
            fileContents+= strlen(textBlockLabel);
    
        fclose(pFile);
    
        free (buffer);
    
        return fileContents;
    }
    
    int main()
    {
        char * content = getTextBlock("example.txt","##TITLE");
        if(content != NULL)
            printf("%s", content);
        return 0;
    }
    

    输出:

    My program
    # 1
    # 2
    ##
    

    有两种模式:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    char* getTextBlock(const char *filename, char *start, char *stop){
        char *fileContents;
    
        FILE * pFile;
        long lSize;
        char * buffer;
        size_t result;
    
        pFile = fopen (filename , "r" );
        if (pFile==NULL) {
            fputs ("File error",stderr);
            return NULL;
        }
    
        // obtain file size:
        fseek (pFile , 0 , SEEK_END);
        lSize = ftell (pFile);
        rewind (pFile);
    
        // allocate memory to contain the whole file:
        buffer = (char*) malloc (sizeof(char)*lSize);
        if (buffer == NULL) {
            fputs ("Memory error",stderr);
            return NULL;
        }
    
        // copy the file into the buffer:
        result = fread (buffer,1,lSize,pFile);
        if (result != (unsigned long)lSize) {
            fputs ("Reading error",stderr);
            return NULL;
        }
    
        fileContents = strstr(buffer, start);
        if(fileContents!= NULL)
            fileContents+= strlen(start);
    
        char *end = strstr(fileContents, stop);
        if(end == NULL)
            return NULL;
        end[0]= '\0';
    
        fclose(pFile);
    
        free (buffer);
    
        return fileContents;
    }
    
    int main()
    {
        char * content = getTextBlock("example.txt","##TITLE", "##");
        if(content != NULL)
            printf("%s", content);
        return 0;
    }
    

    输出:

    My program
    # 1
    # 2
    

    【讨论】:

    • 很好奇,为什么在ftell() 返回long 时使用unsigned long lSize;.... lSize = ftell (pFile); 类型?
    • @RoadRunner 对我来说只是自定义:(type *) malloc (sizeof (type) * length);
    • 不要使用已经free'd 的区域。
    • 这是未定义的行为。
    • 为了让strstr 在所有情况下都能正常工作,您的buffer 应该以空值结尾。
    猜你喜欢
    • 2020-05-11
    • 2014-02-26
    • 2017-09-13
    • 1970-01-01
    • 2012-07-28
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多