[英]How to read data from all files in a directory using C Language?
I am trying to 1) Find all files in a directory and display them, 2) Open all found files and read data from them (characters) 3) Output the read data to the screen or a new file. 我正在尝试1)查找目录中的所有文件并显示它们,2)打开所有找到的文件并从中读取数据(字符)3)将读取的数据输出到屏幕或新文件。
This is done in C Language and you will see below my current code. 这是用C语言完成的,您将在我当前的代码下面看到。 The problem that I am running into is that: I can find all the files in my directory and print them to the screen just fine (point 1 above), but when I try to open the found files and read data (characters) from them (point 2 above), I get a segmentation fault.
我遇到的问题是:我可以找到目录中的所有文件并将它们打印到屏幕上(上面的第1点),但是当我尝试打开找到的文件并从中读取数据(字符)时(以上第2点),我遇到了细分错误。
If I comment out the fscanf(entry_file, "%s", files);
如果我注释掉
fscanf(entry_file, "%s", files);
line below, but leave the entry_file = fopen(in_file->d_name, "r");
在下面一行,但保留
entry_file = fopen(in_file->d_name, "r");
line, it compiles okay and writes the files to the screen. 行,可以编译,然后将文件写入屏幕。 I also tried indexing the
fscanf
line with the int i
(not shown below) and produced the same segmentation fault. 我还尝试用
int i
(以下未显示)对fscanf
行进行索引,并产生相同的分段错误。
So, how can I read data from these found files? 那么,如何从这些找到的文件中读取数据? Thanks!
谢谢!
#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;
}
Seeing as you are correctly checking for NULL
against dir
and in_file
before using them, the only other thing that could possibly be causing this is entry_file
being null. 看起来您在使用
dir
和in_file
之前正确地检查了NULL
,唯一可能导致此问题的其他事情是entry_file
为null。 Check it before using it: 使用前先检查一下:
#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;
}
Note also that, as multiple other users have commented, you should close entry_file
within the loop. 还请注意,由于其他多个用户已发表评论,因此您应在循环中关闭
entry_file
。
You will need a function with a loop using fread()
to replace the fscanf
line, and do a hex dump. 您将需要一个带有
fread()
循环的函数来替换fscanf
行,并进行十六进制转储。 For one thing, you don't know if the files are text files or binary files. 一方面,您不知道文件是文本文件还是二进制文件。 For another, the segfault could be coming from reading a binary file that contains no
newline
into char files[1000];
另一方面,段错误可能是由于将不包含
newline
的二进制文件读取到char files[1000];
And even if the files are all text files, you cannot predict that your "generous" 1000 length is enough to hold the first line of text. 而且即使这些文件都是文本文件,您也无法预测您的“大量” 1000长度足以容纳文本的第一行。
The two most likely causes of the crash are not checking the return value of fopen
– then either the fscanf
or the fclose
may crash when attempting to use entry_file
when it's NULL
– and the potential overflow of files
. 崩溃的两个最可能的原因是没有检查
fopen
的返回值-则尝试在entry_file
为NULL
时尝试使用fscanf
或fclose
可能会崩溃-以及files
的潜在溢出。
Another problem which does not cause a crash is that the in_file->d_name
does not contain the full path, but only the name of the file. 另一个不会导致崩溃的问题是
in_file->d_name
不包含完整路径,而仅包含文件名。 So if you are testing the code inside /Users/tcn/data
then it will appear to work, but it will fail elsewhere. 因此,如果您正在
/Users/tcn/data
中测试代码,则该代码似乎可以工作,但在其他地方将失败。 Either prefix the filename with /Users/tcn/data/
or operate only on the current directory ( .
). 给文件名加上
/Users/tcn/data/
前缀,或者仅在当前目录( .
)上操作。
Fixes: 修正:
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);
}
And remove the other fclose(entry_file)
from the end of the code. 然后从代码末尾删除另一个
fclose(entry_file)
。
Also note that if you use this code with an arbitrary directory, it might contain pipes and/or device nodes that will hang forever when you attempt to read them. 还要注意,如果将此代码与任意目录一起使用,则它可能包含管道和/或设备节点,这些管道和/或设备节点在尝试读取它们时将永远挂起。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.