比较目录C中所有文件的内容

时间:2019-01-06 22:40:23

标签: c arrays

我需要制作一个程序来比较目录中所有文件的内容并检测重复项。程序可以正常工作,直到它开始比较for循环内的文件。我认为数组中可能有错误,但找不到。任何帮助将不胜感激。

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include <stdlib.h>

int listFiles(char *path, int a, char ***array);

int main() {
    char path[100];
    char **array = NULL;
    int a = 0;
    printf("Enter path to list files: ");
    scanf("%s", path);
    listFiles(path, a, &array);
    return 0;
}

int listFiles(char *basePath, int a, char ***array) {
    char path[1000], c, *d = NULL;
    FILE *input_file;
    struct dirent *dp;
    DIR *dir = opendir(basePath);
    if (!dir) {
        return 1;
    }
    while ((dp = readdir(dir)) != NULL) {
        if (strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0) {
            strcpy(path, basePath);
            strcat(path, "\\");
            strcat(path, dp->d_name);
            input_file = fopen(path, "r");
            if (input_file == NULL) {
                fclose(input_file);
            }
            if (input_file) {
                printf("%s\n", path);
                while ((c = getc(input_file)) != EOF)
                    d = realloc(d, (x + 1) * sizeof(*d));
                (d)[x++] = c;
            }
            *array = realloc(*array, (a + 1) * sizeof(**array));
            (*array)[a++] = d;
            if (a > 1) {
                for (int j = 0; j < a - 1; ++j) {
                    if (!memcmp(array[a], array[j], 999)) {
                        printf("duplikat\n");
                        free(array[a]);
                        --a;
                        break;
                    }
                }
            }
        }
        listFiles(path, a, array);
    }
    closedir(dir);
    return 0;
}

1 个答案:

答案 0 :(得分:3)

while ((c = getc(input_file)) != EOF)
d=realloc(d, (x+1)*sizeof(*d));
(d)[x++] = c;

等于:

while ((c = getc(input_file)) != EOF) {
   d = realloc(d, (x+1)*sizeof(*d));
}
(d)[x++] = c;

从文件中读取直到EOF,然后为文件中的每个字符重新分配大小相同的d指针。然后,将EOF的值分配给d中的最后一个元素。因此,文件内容不会保存在d指针中。

  1. 始终显式使用{}(除非不使用的情况除外)。
  2. 检查是否溢出。

    size_t pathsize = sizeof(path);
    assert(pathsize > strlen(basePath) + 1 + strlen(dp->d_name) + 1);
    strcpy(path, basePath);
    strcat(path, "\\");
    strcat(path, dp->d_name);
    

    每次执行危险操作时都要进行类似的检查。

  3. 关闭NULL文件有什么意义?

        if(input_file == NULL){
            fclose(input_file);
        }
        if (input_file){
    
  4. 数字999非常神奇。

    memcmp(array[a],array[j],999)
    
  5. 您错误地处理了数组。或不释放内存。我不知道。

    *array = realloc(*array, (a+1)*sizeof(**array));
    (*array)[a++] = d;
    ...
    free(array[a]);
    
  6. char ***变量中有一点。请勿使用***(除非您使用它们)。 char***array可以完全删除。

  7. 从一个好的抽象开始。首先编写一个将比较两个文件bool files_compare(const char *file1, const char *file2);的函数。然后编写一个函数,该函数将列出目录中的所有文件。然后对列出的每对文件进行比较。几乎没有必要将文件的内容存储在动态内存中(如果文件的大小为10Gb,而系统的内存为1Gb,该怎么办?)。

  8. 如果目录中至少有一个文件,listFiles函数将无休止地递归调用自身。

    int listFiles(char *basePath, int a, char ***array)
    {
        ...
        DIR *dir = opendir(basePath);
        ...
        while ((dp = readdir(dir)) != NULL){
           ...
           listFiles(path,a,array);
      }
    }
    
  9. 此代码有很多错误。它会重用旧的内存,错误地处理数组,具有一些奇怪的幻数,泄漏内存,不会关闭打开的文件,没有受到溢出保护,并递归打开目录。

相关问题