c -从文件读取并设置偏移量



我是C的新手,我正在尝试构建一个C程序,通过扫描文件直到EOF,挑选出包含某个关键字的行,然后在最后一行搜索后设置偏移量。当再次执行扫描时,它扫描文件,这次从保存的偏移量开始,一直向下直到EOF。

我正试图围绕文件I/O的不同函数包装我的头,我有麻烦拼凑过程调用fopen(), fseek(), fgets(), ftell()等做我想做的事情。谁能给我指出正确的方向,或者告诉我该怎么做?

谢谢!

我建议在您的情况下使用getline进行读取,ftellfseek用于获取/设置偏移量(strstr用于搜索单个行)。

我不确定我理解你保存偏移量是关于什么的,但它可能看起来像这样:

int pick_lines(const char *filename, const char *keyword, long *offset)
{
    FILE *fp;
    char *line = NULL;
    size_t len = 0;
    if (offset == NULL || (fp = fopen(filename, "r")) == NULL)
        return 1;
    if (*offset > 0 && fseek(fp, *offset, SEEK_SET) != 0) {
        fclose(fp);
        return 1;
    }
    while (getline(&line, &len, fp) != -1) {
        if (strstr(line, keyword) != NULL)
            printf("%s", line); // or do something else with chosen line
    }
    if ((*offset = ftell(fp)) < 0) {
        free(line);
        fclose(fp);
        return 1;
    }
    free(line);
    fclose(fp);
    return 0;
}

这里的offset是一个输入/输出参数。它的解引用值用于查找给定的偏移量(从*offset == 0开始),然后重置为新的偏移量。

这个函数只打印包含keyword的每一行。如果您想返回一个行数组,则需要做一些额外的工作。

用法的一个例子可能是:

long offset = 0;
pick_lines(filename, keyword, &offset);
// append lines to file
pick_lines(filename, keyword, &offset);
// ...

你可以这样做(只是伪代码):

fopen();
offset = loadOffset();
fseek(offset); // set offset from previous run
while(!feof())
{
  fgets();
  if(searchKeyword() == true)
  {
    offset = ftell(); // getting the offset (after the line you just read)
    doSomething();
  }
}
saveOffset(offset);
fclose();

提示:小心使用feof();只有当输入操作因为EOF而失败时,它才返回true。如果文件指针处于EOF,但之前没有任何失败,则返回false。你必须处理这种情况

听起来您想要做的是用一个"header"开始文件,该"header"定义在哪里找到最后一个结果。通过这种方式,信息被写入并存储在文件本身中。8位十六进制值足以表示大小为4GB的文件中的偏移量。比如:

00000022<cr><lf>
Text...<cr><lf>
More text...<cr><lf>
~ <cr><lf>  <-- this '~' is whatever we're looking for
Other stuff...<cr><lf>

我在这里做了一些假设。首先,这是在Windows上,其中文本行以<cr><lf>字符结束(分别为0x0D和0x0A)。如果是Unix,则仅为<lf>。如果是Mac,它可以是<cr>,或者其他任何一个。我在这个例子中计算了它们。这是假设ansi风格的字符串,这意味着8位编码(一个字符=一个字节的数据)。使用Unicode或其他字符串格式也可以实现相同的功能,只是注意它们可能不再是每个字符一个字节。(在Unicode中,每个字符是两个字节。因此,如果混合使用Unicode和ANSI字符串操作,将会出现麻烦。)

这里,"header"值是0x22或34十进制,如果从文件开头开始计算所有字符,在第34次计数时到达'~'。因此,"header"指向最后一次搜索结果的位置。

的工作原理是这样的:最初这个头值是零,所以你的代码会读到这个,并且知道它还没有被搜索。假设代码扫描整个文件,对每个字符加1,直到找到'~'字符。然后它返回到开头,将该计数值转换为8个文本字符(itoasprintf),并用它覆盖文件的这一部分。一个人发现、完成或重新处理整个事情以寻找更多的东西。现在,下次处理该文件时,您的代码将读取该头值,并将其从文本转换为uint (atoi),查找该文件到此偏移量加上一个(因为我们不想再次捕获此偏移量),然后再次开始扫描。

这里的其他人有一些很好的实际代码示例,可以开始试验。注意,如果要查找的不仅仅是一个字符,比如一个单词或一串数字,那么扫描部分会变得更慢、更复杂。复杂的"标记"扫描而不是简单的字符或单词被称为词典分析,这是另一个话题。谷歌Flex and BisonYACC

最新更新