在循环

时间:2016-04-20 07:59:44

标签: c file loops pointers

好吧,伙计们,我在使用文件指针通过循环遍历文件时遇到了一些麻烦。我将在我的文本文件中有一个字符串列表,每行一个,我正在测试它们之间的相似之处。所以我的方法是使用两个文件指针进行遍历和比较。

示例:FILE* fp1将在第一行开始设置。 FILE* fp2将在第二行开始设置。

我希望以这种方式穿越:

Line 1 <-> Line 2
Line 1 <-> Line 3
Line 1 <-> Line 4
Line 1 <-> Line 5

(这里我通过fp1读取下一行到达第2行,我也尝试将fp2设置为fp1后读取的下一行)

Line 2 <-> Line 3
Line 2 <-> Line 4
Line 2 <-> Line 5

等等...

以下是代码... FILE* fp已作为(FILE* fp)传递给函数

FILE* nextfp;
for(i = 1; i <= numStr; i++){
    fscanf(fp, "%s", str1);
    nextfp = fp;
    double str1len = (double)(strlen(str1));
    for(j = i + 1; j <= numStr; j++){
        fscanf(nextfp, "%s", str2);
        double str2len = (double)(strlen(str2));

        if((str1len >= str2len) && ((str2len / str1len) >= 0.90000) && (lcsLen(str1, str2) / (double)str2len >= 0.80000))
            sim[i][j] = 'H';
        else if ((str2len >= str1len) && ((str1len / str2len) >= 0.90000) && (lcsLen(str2, str1) / (double)str1len >= 0.80000))
            sim[i][j] = 'H';
    }
}

int numStr是带字符串
的总行数 lcsLen(char*, char*)返回最长公共子序列的长度

sim[][]数组是我标记相似程度的地方。截至目前,我只对它进行了编程,以标记高度相似的字符串。

我的结果不完整,这是由于我的fp没有进入下一行而只是停留在同一个字符串上,而且,我的内部循环是让nextfp指向最后一个字符串而不是去哪里这应该归功于我的nextfp = fp行。

任何帮助表示赞赏!非常感谢你们!

3 个答案:

答案 0 :(得分:1)

你不能像对待内存的指针那样对待FILE *,它是指向FILE类型对象的指针,而对象又保存与文件I / O相关的状态

复制FILE *毫无意义,当然也无法创建相关的副本。

该状态的一部分是文件中的当前位置,这不会因为您复制指针而改变。

您应该调查内存映射文件,这将为您提供您期望的访问类型,或者只需将整个文件读入一个字符串数组,然后您可以以任何方式迭代等。

答案 1 :(得分:0)

在第一个内部循环之后,文件流已经转到文件结尾。之后,您无法使用fp从文件流中读取。记住你正在阅读,溪流不要回去。阅读man 3 fseek,你可以手动将文件偏移设置到某个地方,但这并不能解决你的问题。您应该读取阵列的所有行,这更容易,更快。

答案 2 :(得分:0)

当其他答案陈述时,您应该考虑将整个文件读入数组。如果您的文件大小超过几百MB,那么您的方法可能是正确的选择。

使用ftell在读取第一行后保存当前偏移量,并在循环完其余行后用fseek将文件描述符设置回该偏移量。

FILE* nextfp;
size_t offset;
for(i = 1; i <= numStr; i++){
    fscanf(fp, "%s", str1);
    offset = ftell(fp); // save the current position
    double str1len = (double)(strlen(str1));
    for(j = i + 1; j <= numStr; j++){
        fscanf(nextfp, "%s", str2);
        double str2len = (double)(strlen(str2));

        if((str1len >= str2len) && ((str2len / str1len) >= 0.90000) && (lcsLen(str1, str2) / (double)str2len >= 0.80000))
            sim[i][j] = 'H';
        else if ((str2len >= str1len) && ((str1len / str2len) >= 0.90000) && (lcsLen(str2, str1) / (double)str1len >= 0.80000))
            sim[i][j] = 'H';
    }
    fseek(fp, offset, SEEK_SET); // set the file descriptor back to the previous position
}