繁体   English   中英

如何使用C语言从目录中的所有文件读取数据?

[英]How to read data from all files in a directory using C Language?

我正在尝试1)查找目录中的所有文件并显示它们,2)打开所有找到的文件并从中读取数据(字符)3)将读取的数据输出到屏幕或新文件。

这是用C语言完成的,您将在我当前的代码下面看到。 我遇到的问题是:我可以找到目录中的所有文件并将它们打印到屏幕上(上面的第1点),但是当我尝试打开找到的文件并从中读取数据(字符)时(以上第2点),我遇到了细分错误。

如果我注释掉fscanf(entry_file, "%s", files); 在下面一行,但保留entry_file = fopen(in_file->d_name, "r"); 行,可以编译,然后将文件写入屏幕。 我还尝试用int i (以下未显示)对fscanf行进行索引,并产生相同的分段错误。

那么,如何从这些找到的文件中读取数据? 谢谢!

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

int main()
{
    DIR* dir;
    FILE *entry_file;
    struct dirent *in_file;
    char files[1000];
    int i;

    dir = opendir("/Users/tcn/data");

    if(dir==NULL){
        printf("Error! Unable to read directory");
        exit(1);
    }

    while( (in_file=readdir(dir)) != NULL) {
        if (!strcmp (in_file->d_name, "."))
            continue;
        if (!strcmp (in_file->d_name, ".."))
            continue;
        printf("%s\n", in_file->d_name);
        entry_file = fopen(in_file->d_name, "r");

        fscanf(entry_file, "%s", files); 
    }

    closedir(dir);
    fclose(entry_file);
    return 0;
}

看起来您在使用dirin_file之前正确地检查了NULL ,唯一可能导致此问题的其他事情是entry_file为null。 使用前先检查一下:

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

int main()
{
    DIR* dir;
    FILE *entry_file;
    struct dirent *in_file;
    char files[1000];
    int i;

    dir = opendir("/Users/tcn/data");

    if(dir==NULL) {
        printf("Error! Unable to read directory");
        exit(1);
    }

    while((in_file=readdir(dir)) != NULL) {
        if (!strcmp (in_file->d_name, "."))
            continue;
        if (!strcmp (in_file->d_name, ".."))
            continue;
        printf("%s\n", in_file->d_name);
        entry_file = fopen(in_file->d_name, "r");
        if (entry_file != NULL) {
            fscanf(entry_file, "%s", files);
            /* whatever you want to do with files */
            fclose(entry_file);
        }
    }

    closedir(dir);
    return 0;
}

还请注意,由于其他多个用户已发表评论,因此您应循环中关闭entry_file

您将需要一个带有fread()循环的函数来替换fscanf行,并进行十六进制转储。 一方面,您不知道文件是文本文件还是二进制文件。 另一方面,段错误可能是由于将不包含newline的二进制文件读取到char files[1000]; 而且即使这些文件都是文本文件,您也无法预测您的“大量” 1000长度足以容纳文本的第一行。

崩溃的两个最可能的原因是没有检查fopen的返回值-则尝试在entry_fileNULL时尝试使用fscanffclose可能会崩溃-以及files的潜在溢出。

另一个不会导致崩溃的问题是in_file->d_name不包含完整路径,而仅包含文件名。 因此,如果您正在/Users/tcn/data中测试代码,则该代码似乎可以工作,但在其他地方将失败。 给文件名加上/Users/tcn/data/前缀,或者仅在当前目录( . )上操作。

修正:

if ((entry_file = fopen(in_file->d_name, "r"))) {
    (void) printf("%s\n", in_file->d_name);
    if (fgets(files, sizeof files, entry_file)) { // or `while`?
        // do something with `files`, it will be overwritten for next file
    }
    (void) fclose(entry_file);
}

然后从代码末尾删除另一个fclose(entry_file)

还要注意,如果将此代码与任意目录一起使用,则它可能包含管道和/或设备节点,这些管道和/或设备节点在尝试读取它们时将永远挂起。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM