【问题标题】:Working with two files in C在 C 中处理两个文件
【发布时间】:2016-09-27 08:14:21
【问题描述】:

我正在阅读一个名为“text.txt”的文件,其中包含一系列数字,中间有一个空格。我想在一个名为“text_nr.txt”的新文件中写入“text.txt”中的所有数字,但不重复!我的代码在第二个 while 循环中无限循环运行,但我不明白为什么。

#include <stdio.h>
#include <stdlib.h>


int main()
{
    int n=0,m=0,nr;

    FILE *fp1;
    FILE *fp2;
    fp1 = fopen("text.txt","r");
    fp2 = fopen("text_nr.txt","a+");

    while(fscanf(fp1,"%d",&n) != EOF){
        nr=0;
        while(fscanf(fp2,"%d",&m) != EOF){
            printf("%d  %d ",m,n);
            if(n != m) continue;
            else{
                nr++;
                break;
            }
        }   
        if(nr == 0){
            fprintf(fp2,"%d ",n);
        }
    }

    fclose(fp1);
    fclose(fp2);

    return 0;      
}

【问题讨论】:

  • 在输入中的某个时刻,fscanf 的格式不匹配,因此 fscanf 返回 0 但不推进文件指针。所以它一直从同一个位置读取,每次都返回 0。
  • 考虑使用调试器。好有趣! :-)
  • @WilliamPursell 它在第一次开始运行时会这样做。我刚刚开始处理文件,我不知道为什么会这样。你能再解释一下,以便我理解并解决这个问题吗?
  • 我对这些类型问题的一般处理方法是永远不要使用 scanf,所以我不是帮助的人! IMO,scanf 很复杂,如果您使用freadstrtol 代替,您将了解更多。
  • @WilliamPursell 谢谢,我会尝试另一种方法!

标签: c file loops


【解决方案1】:

fscanf() 这样的函数返回各种值,如 EOF(文件结束或错误)或匹配的说明符数量,01,...

而不是测试一个值代码需要停止,测试所有不需要的值。

// while(fscanf(fp1,"%d",&n) != EOF){
while(fscanf(fp1,"%d",&n) == 1){
    nr=0;
    // while(fscanf(fp2,"%d",&m) != EOF){
    while(fscanf(fp2,"%d",&m) == 1){

@William Pursell解释的很好

在输入中的某个点,fscanf 的格式不匹配,因此 fscanf 返回 0 但不推进文件指针。所以它一直从同一个位置读取,每次都返回 0。

无限循环。

【讨论】:

  • 创意许可'line' -&gt; 'like'在第一行:)
【解决方案2】:

您的内部循环不会到达文件末尾,因为如果文件开始为空,它将与您的搜索字符串不匹配。

您可以执行fscanf 并检查它是0(找不到任何东西)还是EOF(打到最后)。

【讨论】:

  • 如果文件为空,第一次开始读取的时候不会打到EOF吗?
  • 即使你在一个空文件的开头,你也没有碰到 EOF 标志,所以没有。 (为了清楚起见,更新了答案)
  • 即使第二个文件不是空的,它仍然在无限循环中运行。试着把一些数字放在那里
  • 如果将 "!= EOF" 更改为 "== 1" 会得到什么?
【解决方案3】:

尝试使用fseek函数在输出文件中移动流指针。

 while(fscanf(fp1,"%d",&n) != EOF){

    fseek ( fp2, 0 , SEEK_SET );
    bool flag = false;

    while(fscanf_s(fp2,"%d",&m) != EOF){
        printf("%d  %d ",m,n);

        if(n == m) 
        {
            printf("%d = %d ", m, n);
            flag = true;


            break;
        }
    }   
    if(!flag)
    {
        fseek ( fp2, 0 , SEEK_END );
        fprintf(fp2,"%d ",n);
    }
}

编辑

另一种方法是将写入的值存储在数组中。为此,您可以使用矢量。

vector<int> vData;

while(fscanf(fp1,"%d",&n) != EOF){


    bool flag = false;

    for(int i = 0; i < vData.size(); i++)
    {
        if(vData[i] == n)
        {
            flag = true;
            break;
        }
    }

    if(!flag)
    {
        vData.push(n);
        fprintf(fp2,"%d ",n);
    }
}

【讨论】:

  • 它仍然在无限循环中运行!
  • 我做了一些改变。你在比较什么数字?
  • 这不会改变任何东西,程序在这里失败:while(fscanf(fp2,"%d",&m) != EOF){ printf("%d %d ",m,n );
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-20
  • 2012-05-14
  • 2010-11-26
  • 1970-01-01
  • 2015-10-30
  • 2012-05-10
  • 1970-01-01
相关资源
最近更新 更多