我试图让我的函数在文件末尾停止,但它不起作用

Posted

技术标签:

【中文标题】我试图让我的函数在文件末尾停止,但它不起作用【英文标题】:Im trying to get my function to stop at the end of the file, but its not working 【发布时间】:2022-01-13 01:29:59 【问题描述】:

这段代码基本上应该从两个文件中读取一个数字,确定哪个较小,将较小的一个写入输出文件,获取一个新数字,冲洗并重复。它在大多数情况下都做得很好,但是当它到达终点时它不会停止。我尝试使用 EOF 告诉它在到达文件末尾时停止,但它只是无限循环并将​​最后一个数字添加到输出文件中,所以它看起来不像它应该的“123456789”,它最终看起来就像“123456788999999999999”一样,8 打印两次,而 9 只是无限重复。我使用EOF错了吗?或者我是否需要完全做其他事情,请记住我对 c 很陌生并且不知道很多事情。

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


void mergeFuncs(FILE* num1txt, FILE* num2txt, FILE* outtxt);

int main(int argc, char* argv[]) 
    FILE* num1txt;
    num1txt = fopen("numbers1.txt", "r");
    if (num1txt == NULL) 
        printf("Error opening numbers1.txt!");
        exit(1);
    
    FILE* num2txt;
    num2txt = fopen("numbers2.txt", "r");
    if (num2txt == NULL) 
        printf("Error opening numbers2.txt!");
        exit(1);
    
    FILE* outtxt;
    outtxt = fopen("output.txt", "w");
    if (outtxt == NULL) 
        printf("Error opening output.txt!");
        exit(1);
    
    mergeFuncs(num1txt, num2txt, outtxt);
    return 0;


void mergeFuncs(FILE* num1txt, FILE* num2txt, FILE* outtxt) 
    int num1, num2, loop = 1, endOfFile1, endOfFile2;
    endOfFile1 = fscanf(num1txt, "%d", &num1);
    printf("in getNum1 - %d\n", num1);

    endOfFile2 = fscanf(num2txt, "%d", &num2);
    printf("in getNum2 - %d\n", num2);
    while (loop) 
        printf("\nStart of a new loop! num1 is [%d], and num2 is [%d]\n", num1, num2);
        if (endOfFile1 == EOF && endOfFile2 == EOF) 
            if (num1 < num2) 
                fprintf(outtxt, "%d", num1);
                printf("num1 is smaller\n");
                fprintf(outtxt, "%d", num2);
                printf("done :) //uwu//");
                fclose(num1txt);
                fclose(num2txt);
                fclose(outtxt);
            
            else if (num2 < num1) 
                fprintf(outtxt, "%d", num2);
                printf("num2 is smaller\n");
                fprintf(outtxt, "%d", num1);
                printf("done :) //uwu//");
                fclose(num1txt);
                fclose(num2txt);
                fclose(outtxt);
            
            loop = 0;
        
        else if (endOfFile1 == EOF) 
            fprintf(outtxt, "%d", num1);
            while (endOfFile2 !=EOF) 
                fprintf(outtxt, "%d", num2);
            
            fprintf(outtxt, "%d", num2);
            loop = 0;
            fclose(num1txt);
            fclose(num2txt);
            fclose(outtxt);
        
        else if (endOfFile2 == EOF) 
            fprintf(outtxt, "%d", num2);
            while (endOfFile1 != EOF) 
                printf(outtxt, "%d", num1);
            
            printf(outtxt, "%d", num1);
            loop = 0;
            fclose(num1txt);
            fclose(num2txt);
            fclose(outtxt);
        
        else if (num1 < num2) 
            fprintf(outtxt, "%d", num1);
            printf("num1 is smaller\n");
            endOfFile1 = fscanf(num1txt, "%d", &num1);
            printf("in getNum1 - %d\n", num1);
        
        else if (num2 < num1) 
            fprintf(outtxt, "%d", num2);
            printf("num2 is smaller\n");
            endOfFile2 = fscanf(num2txt, "%d", &num2);
            printf("in getNum2 - %d\n", num2);
        
    
    return;

【问题讨论】:

while (endOfFile1 != EOF) printf(outtxt, "%d", num1); 之类的内容应该会引起您的注意。 endOfFile1 在那个循环中永远不会更新,那么循环怎么会结束呢? printf 的参数也是错误的,应该是 fprintf。编译器真的让你放弃了吗? 也许检查documentation for fscanf,以及它返回的内容,可能会有所了解。 【参考方案1】:

您希望有一个从文件中读取的位置。读两篇,直到读完为止。如果一个文件先用完,则用一个虚假的大值填充其值(limits.h 中的 INT_MAX 是一个不错的选择),以便将另一个值用作最小值。您的功能可以实现为:

void
mergeFuncs(FILE* num1txt, FILE* num2txt, FILE* outtxt)

    int a, b, c = INT_MAX, d = INT_MAX;
    while(
        a = fscanf(num1txt, "%d", &c),
        b = fscanf(num2txt, "%d", &d),
        a == 1 || b == 1
    )
        fprintf(outtxt, "%d,", c > d ? d : c);
        c = d = INT_MAX;
    
    return;

请注意,上述内容不区分到达文件末尾、无效输入或读取错误。如果您关心这种区别,请使用feof 和/或ferror 来决定是否发出适当的错误消息。修改上述内容以处理无效输入是一个很好的练习。

此外,在 scanf 失败后尝试从文件中读取数据可能并不理想,因此您可能会使用类似的东西短路较短文件(或具有读取错误或无效输入的文件)上的读取:

void
mergeFuncs(FILE* num1txt, FILE* num2txt, FILE* outtxt)

    int a = 1, b = 1, c = INT_MAX, d = INT_MAX;
    while(
        a = a == 1 ? fscanf(num1txt, "%d", &c) : 0,
        b = b == 1 ? fscanf(num2txt, "%d", &d) : 0,
        a == 1 || b == 1
    )
        fprintf(outtxt, "%d,", c > d ? d : c);
        c = d = INT_MAX;
    
    return;

请注意,通过这种短路,很难区分读取错误和无效输入。修复这个问题留给读者作为练习。

还请注意,如果您的输入文件看起来像 15233181,则输出文件将不是1121 而是 1523,因为这些输入中的每一个都只是一个整数。 scanf 不读取单个数字。如果要读取单个数字,则需要进行修改。您对输出文件的评论类似于 123456788999999999999 表明您可能希望使用 %c 转换说明符来读取单个数字。我在输出中的每个值后添加了一个逗号,以帮助阐明这一点。

【讨论】:

【参考方案2】:

而不是依赖 fscanf 的返回值,它可能会或可能不会实际返回 EOF,而是使用 feof 来确定文件是否为空。

根据fscanf 的规范,仅当文件已经为空时才返回 EOF,但在您的情况下,您可以在文件末尾有尾随空格,fscanf 不会消耗,因为没有数据在它之后匹配。

【讨论】:

以上是关于我试图让我的函数在文件末尾停止,但它不起作用的主要内容,如果未能解决你的问题,请参考以下文章

试图在 Python 脚本中复制文件,但它不起作用

试图为不和谐制作一个聊天机器人,但它不起作用

使用Tkinter我试图添加用户输入的值并将其添加到文件中存在的值,但它不起作用

如果该记录尚不存在但它不起作用,我试图仅将新记录插入数据库

试图在每 1 分钟后执行一项工作,但它不起作用?

试图将 ViewController 中的字符串传递给 NSObject 中的字符串 .. 但它不起作用