You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言用动态数组读取文件对比,差异文件为空的问题求助

文件对比程序无差异输出问题排查

我尝试将两个输入文件的内容读取到与文件大小匹配的动态分配char指针中,逐个对比字符,把第二个文件与第一个文件的差异写入新文件。但程序执行后,存储第二个文件差异的文件为空,不确定是文件读取环节还是其他问题导致的。

主函数代码

int main(int argc, char * argv[]){

  int file1 = -1, file2 = -1, fileDif1 = -1, fileDif2 = -1;
  file1 = open(argv[1], O_RDONLY);
  file2 = open(argv[2], O_RDONLY);
  fileDif1 = open("differencesFoundInFile1.txt", O_WRONLY | O_CREAT | O_TRUNC, 0600);
  fileDif2 = open("differencesFoundInFile2.txt", O_WRONLY | O_CREAT | O_TRUNC, 0700);
  handleExceptions(argc, argv[1], argv[2], file1, file2, fileDif1, fileDif2);

  step1(file1, file2, fileDif1);
  step2(argv[1], argv[2], file1, file2, fileDif2);

  close(file1);
  close(file2);
  close(fileDif1);
  close(fileDif2);
  return 0;
}

疑似出错的step2代码

void step2(const char * argv1, const char * argv2, int file1, int file2, int fileDif2) {
    struct timeval begin, end;
    gettimeofday(&begin, NULL);

    struct stat fileStat1;
    struct stat fileStat2;
    stat(argv1, &fileStat1);
    stat(argv2, &fileStat2);
    int size1 = fileStat1.st_size;
    int size2 = fileStat2.st_size;

    char * fileArray1 = malloc(size1), * fileArray2 = malloc(size2); //create array
    read(file1, fileArray1, size1); //store bytes in array
    read(file2, fileArray2, size2); //store bytes in array

    //check for differences and write to file if found
    for(int i = 0; i < size2; i++){
        if(fileArray1[i] != fileArray2[i]){
            write(fileDif2, &fileArray2[i], 1);
        }
    }

    free(fileArray1);
    free(fileArray2);

    //calculate time of completion
    gettimeofday(&end, NULL);
    printf("Step 2 took %f milliseconds\n",
           (((double)end.tv_usec / 1000) - ((double)begin.tv_usec / 1000)));
}

step1代码

void step1 (int file1, int file2, int fileDif1) {
    struct timeval begin, end;
    gettimeofday(&begin, NULL); //begin timer
    int bufferSize = 2;
    char * buffer1 = (char *) malloc(sizeof(char) * bufferSize), * buffer2 = (char *) malloc(sizeof(char) * bufferSize);
    buffer1[bufferSize - 1] = '\0';
    buffer2[bufferSize - 1] = '\0';

    int bytesRead = read(file1, buffer1, bufferSize - 1);
    read(file2, buffer2, bufferSize - 1);
    while(bytesRead > 0){
        buffer1[bytesRead] = '\0';
        buffer2[bytesRead] = '\0';
        if(*buffer1!=*buffer2) {
            write(fileDif1, buffer1, bytesRead);
        }
        bytesRead = read(file1, buffer1, bufferSize - 1);
        read(file2, buffer2, bufferSize - 1);
    }

    free(buffer1);
    free(buffer2);

    gettimeofday(&end, NULL);
    printf("Step 1 took %f milliseconds\n",
           (((double)end.tv_usec / 1000) - ((double)begin.tv_usec / 1000)));
}

引用的头文件

#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>

问题根源及修复方案

1. 文件指针偏移问题

主函数中先调用step1,step1会将file1和file2的文件指针读到末尾。后续调用step2时,直接用这两个文件描述符执行read,会从当前偏移位置(文件末尾)开始读取,读取字节数为0,导致fileArray1和fileArray2为空,自然无差异输出。

修复:在step2的read操作前,将文件指针重置到开头:

// 添加在read(file1, ...)之前
lseek(file1, 0, SEEK_SET);
lseek(file2, 0, SEEK_SET);

2. 边界越界问题

当第二个文件长度大于第一个时,循环到i >= size1时,fileArray1[i]会访问malloc分配内存之外的区域,触发未定义行为。同时,第二个文件超出第一个文件长度的部分也应视为差异。

修复:调整循环逻辑,处理文件长度不一致的情况:

int maxSize = size1 > size2 ? size1 : size2;
for(int i = 0; i < maxSize; i++){
    // 任一文件到末尾,或字符不同时,记录第二个文件的字符
    if(i >= size1 || i >= size2 || fileArray1[i] != fileArray2[i]){
        if(i < size2){
            write(fileDif2, &fileArray2[i], 1);
        }
    }
}

3. 错误检查缺失

当前代码未检查malloc和read的返回值,内存分配失败或文件读取失败时会导致后续逻辑异常。

修复:添加错误检查:

// 检查malloc返回值
char * fileArray1 = malloc(size1);
char * fileArray2 = malloc(size2);
if(fileArray1 == NULL || fileArray2 == NULL){
    perror("malloc failed");
    exit(EXIT_FAILURE);
}

// 检查read返回值
ssize_t bytesRead1 = read(file1, fileArray1, size1);
ssize_t bytesRead2 = read(file2, fileArray2, size2);
if(bytesRead1 != size1 || bytesRead2 != size2){
    perror("read failed");
    free(fileArray1);
    free(fileArray2);
    exit(EXIT_FAILURE);
}

4. 计时逻辑错误

原计时代码只计算微秒差,未处理秒数变化,会导致时间计算错误。

修复:修正时间差计算方式:

double elapsed = (end.tv_sec - begin.tv_sec) * 1000.0 + (end.tv_usec - begin.tv_usec) / 1000.0;
printf("Step 2 took %f milliseconds\n", elapsed);

内容的提问来源于stack exchange,提问作者Zodiac

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 12:33:13