【问题标题】:Using file pointers while looping循环时使用文件指针
【发布时间】:2016-08-12 18:06:54
【问题描述】:

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

示例: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 行。

任何帮助表示赞赏!非常感谢大家!

【问题讨论】:

  • 根据文件的大小,我建议您读入内存中的数组,而不是摆弄文件读取。然后是数组索引的简单嵌套循环。
  • 它将是任意大小。我是这样接近的,所以我不必担心记忆。
  • 为什么你使用浮点类型作为字符串长度?什么时候字符串的长度都是非整数?除法时可以转换为浮点数。
  • 我用它作为一种绕过整数算术的方法(尽管我可以很好地进行计算)

标签: c file loops pointers


【解决方案1】:

在第一个内部循环之后,文件流已经进入文件结尾。之后,您不能使用 fp 从文件流中读取。记住你正在阅读流,流不回去。阅读 man 3 fseek,您可以手动将文件偏移量设置到某个位置,但这并不能解决您的问题。您应该读取所​​有行到数组,这更容易和更快。

【讨论】:

    【解决方案2】:

    您不能将FILE * 视为指向内存的指针,它是指向FILE 类型对象的指针,而该对象又持有与文件I/O 关联的状态。

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

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

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

    【讨论】:

      【解决方案3】:

      正如其他答案所述,您应该考虑将整个文件读入一个数组。如果您的文件大小超过数百 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
      }
      

      【讨论】:

        猜你喜欢
        • 2013-06-26
        • 1970-01-01
        • 2018-07-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多