比较c中的两个txt文件

比较c中的两个txt文件,c,fgets,strcmp,C,Fgets,Strcmp,我试图比较两个文本文件并打印它们不同的第一行,但我在fgets()命令中使用了500的缓冲区,我认为这是在浪费空间。 如果我不知道线的长度,我如何制作相同的程序 这是我的密码: #include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char const *argv[]) { FILE *fp1, *fp2; int nLine = 1;

我试图比较两个文本文件并打印它们不同的第一行,但我在fgets()命令中使用了500的缓冲区,我认为这是在浪费空间。 如果我不知道线的长度,我如何制作相同的程序

这是我的密码:

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

int main(int argc, char const *argv[])
{
    FILE *fp1, *fp2;

    int nLine = 1;
    char l1[500], l2[500];

    system("clear");

    if (argc < 3)
    {
        printf("Usage: %s <file1.txt> <file2.txt>\n",argv[0]);
        exit(1);
    }

    if ((fp1 = fopen(argv[1],"r")) == NULL){
        printf("Can't open file: %s\n", argv[1]);
        exit(1);
    }

    if ((fp2 = fopen(argv[2],"r")) == NULL){
        printf("Can't open file: %s\n", argv[2]);
        exit(1);
    }

    fgets(l1,500,fp1);
    fgets(l2,500,fp2);

    while ((l1 != 0) && (l2 != 0)){
        if(strcmp(l1,l2) != 0){
            printf("Line number: %d\n", nLine);
            printf("%s", l1);
            printf("%s\n", l2);
            exit(1);
        } else {
            fgets(l1,500,fp1);
            fgets(l2,500,fp2);
            nLine++;    
        }   
    }

    return 0;
}
#包括
#包括
#包括
int main(int argc,char const*argv[]
{
文件*fp1,*fp2;
int-nLine=1;
字符l1[500],l2[500];
系统(“清除”);
如果(argc<3)
{
printf(“用法:%s\n”,argv[0]);
出口(1);
}
if((fp1=fopen(argv[1],“r”)==NULL){
printf(“无法打开文件:%s\n”,argv[1]);
出口(1);
}
if((fp2=fopen(argv[2],“r”)==NULL){
printf(“无法打开文件:%s\n”,argv[2]);
出口(1);
}
fgets(L1500,fp1);
fgets(L2500,fp2);
而((l1!=0)和&(l2!=0)){
if(strcmp(l1,l2)!=0){
printf(“行号:%d\n”,nLine);
printf(“%s”,l1);
printf(“%s\n”,l2);
出口(1);
}否则{
fgets(L1500,fp1);
fgets(L2500,fp2);
nLine++;
}   
}
返回0;
}
如果您不想“浪费空间”,请记住数据在文件内存中。一次读取1个字符。当您发现差异时,只需查找上一行提要的位置并报告以下行

long index = 0;
long index_lf = 0;
int c1,c2;

// read until a difference or done
while ((c1 = fgetc(fp1)) == (c2 = fgetc(fp2)) && (c1 != EOF)) {
  index++;
  if (c1 == '\n') index_lf = index;
}
if (c1 == c2) {
  puts("same");
} else {
  puts("differ");
  fseek(fp1, index_lf, SEEK_SET);
  fseek(fp2, index_lf, SEEK_SET);
  // read and print each file until a following \n or EOF occurs.
  // TBD code for OP
}

[编辑]针对各种问题进行了一些改进:最后一个字节不匹配、以不同模式打开的文件、错误处理等

long offset1 = ftell(fp1);;
long offset2 = ftell(fp2);;
int c1,c2;

// read until a difference or done
while ((c1 = fgetc(fp1)) == (c2 = fgetc(fp2)) && (c1 != EOF)) {
  if (c1 == '\n') {
    offset1 = ftell(fp1);
    offset2 = ftell(fp2);
  }
}

if (offset1 == -1 || offset2 == -1 || ferror(fp1) || ferror(fp2)) {
  puts("problem");
} else if (c1 == c2) {
  puts("same");
} else {
  puts("differ");
  fseek(fp1, offset1, SEEK_SET);
  fseek(fp2, offset2, SEEK_SET);
  // read and print each file until a following \n or EOF occurs.
  // TBD code for OP
}

如果文件没有差异,则有一个无限循环。检查
fgets()
的返回值。您可以比较两个文件中的字符,如果字符不同,则调用函数打印该行。这可能会很棘手,因为我们没有遵循这条路线。您可以反向遍历,直到获得新行字符;然后打印行。实现目标不需要缓冲区。我只需要动态比较对应的字符,并记住在这个过程中遇到的最新换行符。如果文件相同,缓冲区长度就无关紧要了。如果缓冲区的末尾包含一个
换行符
,只需增加行数即可。即使在这种情况下不会有任何区别,但请记住在不再需要每个文件时尽快将其丢失。
if(c1==EOF&&c2==EOF)
条件可以缩短为
if(c1==c2)
,不是吗?