在C中读取文件 - 范围和上下文的问题

时间:2013-02-24 08:34:26

标签: c parsing file-io scope

我必须解析一个文件,该文件有几个以空行分隔的条目。每个条目都具有以下格式:

ab bababa
2
ab bba
b ba

其中:

  1. 第一行:将两个单词用空格分隔。
  2. 第二行:将有一个整数,表示需要考虑多少行
  3. 下一行:将每个单词分成两个单词,用空格分隔。
  4. 在每个条目的末尾,我需要调用一个函数并传递条目中的一些参数。具体来说,我需要传递第一行中找到的前两个单词和一个包含表示整数后面的行的结构的数组。结构定义如下所示:

    typedef struct t_transformation_rule {
        char *needle;
        char *replacement;
    } transformation_rule;
    

    正如我所说,文件可以包含多个条目。因此,特定文件可能如下所示:

    ab bababa
    2
    ab bba
    b ba
    
    a abba
    3
    a bb
    bb abba
    a abba
    
    abcd abcd
    0
    
    abab bbbaaa
    2
    ab aaa
    ab bbb
    

    这是我为解析它而做的,但是我遇到了麻烦,因为当我找到数字时,我初始化一个结构数组,然后我尝试使用该数组并存储下一行,但是该变量超出了范围。这是代码:

    void processFile(char *file_name)
    {
        char buff[120];
        char needle[20], replacement[20];
        char origin[20], target[20];
    
        int num, rule_counter;
        size_t len;
    
        int context,rc;
        transformation_rule *rules_list;
    
        context =0;
        rule_counter = 0;
    
        FILE *in = fopen(file_name,"r");
    
        if (in != NULL) {
          while(fgets (buff, sizeof buff, in)) {
            len = strlen (buff);
            while (len && buff[len-1] == '\n') {
              buff[--len] = 0;
            }
            if (context == 0) {
              rc = sscanf(buff, "%s %s", origin, target);
              context = 1;
            }
            if (context == 1) {
              rc = sscanf(buff, "%d", &num);
              transformation_rule rules_list[num];
              context = 2;
            }
            if (context == 2) {
              if (!len) {
                  context = 0;
                  continue;
              }
              rc = sscanf(buff, "%s %s", needle, replacement);
              transformation_rule *rule = malloc(sizeof(transformation_rule));
    
              rule->needle = needle;
              rule->replacement = replacement;
    
              // HERE I GET THE ERROR SAYING THAT RULES_LIST IS NOT DEFINED
              rules_list[rule_counter] = rule;
              rule_counter++;
            }
    
          }
        }
    }
    

    如果你们能告诉我我做错了什么,或者我怎么能这样做更容易,我真的很感激。

1 个答案:

答案 0 :(得分:2)

是的,可以更简单地完成:您正在阅读fscanf部分,然后使用sscanf进行解析。这是罚款但在这种情况下这可能就是你要找的东西:

#include "stdlib.h"
#include "stdio.h"
#include "string.h"
void process(char* start, char* target, int cRules, char** froms, char** tos) {
    // work with it
}
int main(int argc, char** argv) {
    if(argc!=2) { 
        printf("need filename\n");
        return 1;
    }
    FILE* f = fopen(argv[1], "rb");
    if(!f) {
        printf("wrong filename\n");
        return 2;
    }
    char* start = malloc(1000);
    char* target = malloc(1000);
    int cRules;
    while(fscanf(f, "%s %s %i", start, target, &cRules)!=EOF) {
        printf("\ntask %s->%s\nnumber of rules %i\n", start, target, cRules);
        char** froms = malloc(cRules*sizeof(char*));
        char** tos = malloc(cRules*sizeof(char*));
        int iRule = 0; for(; iRule<cRules; ++iRule) {
            froms[iRule] = malloc(100);
            tos[iRule] = malloc(100);
            if(fscanf(f, "%s %s", froms[iRule], tos[iRule])==EOF) {
                printf("format error\n");
                fclose(f);
                return 3;
            };
            printf("rule %i %s->%s\n", iRule, froms[iRule], tos[iRule]);
        }
        process(start, target, cRules, froms, tos);
        for(iRule = 0; iRule<cRules; ++iRule) {
            free(froms[iRule]);
            free(tos[iRule]);
        }
        free(froms);
        free(tos);
    }
    free(start);
    free(target);
    fclose(f);
    return 0;
}