我是C的新手,我正在尝试构建一个C程序,扫描文件直到EOF,选择包含某个关键字的行,然后在搜索到最后一行后设置一个偏移量。当再次执行扫描时,它会扫描文件,这次从保存的偏移量开始,然后继续向下直到EOF。
我试图绕过File I / O的不同功能,并且我无法将程序拼凑在一起调用fopen(),fseek(),fgets(),ftell()等等。做我想做的事。任何人都可以指出我正确的方向或指导我完成我需要做的事情吗?
谢谢!
答案 0 :(得分:1)
我建议您使用int
进行阅读,getline
和ftell
用于获取/设置偏移量(以及fseek
用于搜索单个行)。< / p>
我不确定我理解您的偏移量的保存是什么,但它可能看起来像这样:
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
答案 1 :(得分:0)
你可以这样做(只是伪代码):
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。你必须处理这种情况。
答案 2 :(得分:0)
听起来你想要做的是用一个“标题”开始文件,它定义了最后一个结果的位置。这样,该信息就被写入并存储在文件本身中。 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次计数时达到'〜'。所以“标题”指向找到最后一个搜索结果的位置。
这是如何工作的:最初这个标头值为零,所以你的代码会读取它并知道它还没有被搜索过。让我们说代码扫描通过文件,每个字符递增1,直到找到'〜'字符。然后它回到开头,将此计数值转换为8个文本字符(itoa
或sprintf
),并用它覆盖文件的这一部分。一个人发现,完成或处理整个事情以寻找更多。现在,下次处理此文件时,您的代码将读取此标头值,并将其从文本转换为uint
(atoi
),将文件搜索到此偏移量加一个(因为我们不想再抓住这个),然后再次开始扫描。
这里的其他人有一些很好的实例代码示例可以开始试验。请注意,如果您要查找的不仅仅是一个字符,例如一个字或一系列数字,扫描部分会变得更慢,更复杂。复杂的“令牌”扫描而不是简单的字符或单词称为词典分析,这是一个完整的其他主题。 Google Flex and Bison
或YACC
等