C opendir() 没有打开一个目录?
C opendir() not opening a directory?
我在 C 语言方面经验不足,但在我的 类 中有一项作业,而且我在打开目录时遇到了一些问题。
该计划的目的是(释义):
- 如果没有提供标志或目录,则列出当前目录中的文件名。
- 如果提供标志 (-l),则列出有关每个文件的更多信息。
- 如果提供了标志和目录,则转至该目录并列出有关该目录中每个文件(或目录)的信息。没有必要通过子目录递归。
它不需要处理只获取目录但没有标志或无效目录的问题。它更像是概念验证。
我已经设法满足第 1 部分和第 2 部分的要求,但第 3 部分总是出现问题,出现分段错误。
我的代码如下:
void recursedirect(char* flag, char* directory)
{
DIR* dir;
struct dirent *entry;
printf("Flag: %s\nDirectory: %s\n\n", flag, directory);
if (flag == NULL)
// No flag provided, therefore only do file names.
{
dir = opendir(".");
entry = readdir(dir);
while (entry != NULL)
{
printf ("%s\n", entry->d_name);
entry = readdir(dir);
}
}
else if (strcmp(flag, "-l") == 0 && directory == NULL)
// No directory provided, but flag provided
{
dir = opendir(".");
entry = readdir(dir);
while (entry != NULL)
{
fileinfo(directory);
entry = readdir(dir);
}
}
else if (strcmp(flag, "-l") != 0)
{
printf("Invalid flag.\n");
}
else
// A directory is provided
{
dir = opendir(directory);
if (dir != NULL)
{
entry = readdir(dir);
while (entry != NULL)
{
fileinfo(directory);
entry = readdir(dir);
}
}
else
printf("Something went wrong. It might be an invalid filename.\n");
}
}
具体来说,最后的 else 语句给我带来了麻烦。我试过给它任何我能想到的文件路径,硬编码和其他方式,但它仍然给我带来问题。我猜这很简单,但我没有足够的经验知道它是什么。
fileinfo
是一个函数,它在给定 DIR
和 dirent
作为参数的情况下打印出文件信息。但是,错误肯定不在我能说的最好的代码中。
编辑:我犯了没有分享所有内容的错误。我的主要方法很简单。
int main (int argc, char** argv)
{
char* flag = argv[1];
char* directory = argv[2];
recursedirect(flag, directory);
}//main
它包括以下内容:
#include <dirent.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
#include <fcntl.h>
fileinfo
函数如下(稍作编辑,我意识到我不再需要给它一个参数 DIR *dir
):
void fileinfo(struct dirent *entry)
{
struct stat fileStats;
stat(entry->d_name, &fileStats);
printf("File Name: %s\n", entry->d_name);
printf("File Size: %d bytes\n", (int) fileStats.st_size);
printf("Number of Blocks: %d\n", (int) fileStats.st_blocks);
printf("Number of Links/References: %d\n", (int) fileStats.st_nlink);
printf("I-Node: %d\n", (int) fileStats.st_ino);
printf("Device ID: %d\n", (int) fileStats.st_dev);
printf("User ID: %d\n", (int) fileStats.st_uid);
printf("Group ID: %d\n", (int) fileStats.st_gid);
stat("alphabet",&fileStats);
printf("Time of Last Access: %s", ctime(&fileStats.st_atime));
printf("Time of Last Modification: %s", ctime(&fileStats.st_mtime));
printf("Time of Last Status Change: %s", ctime(&fileStats.st_ctime));
stat(entry->d_name, &fileStats);
printf("File Permissions: ");
printf((int) (S_ISDIR(fileStats.st_mode)) ? "d" : "-");
printf((int) (fileStats.st_mode & S_IRUSR) ? "r" : "-");
printf((int) (fileStats.st_mode & S_IWUSR) ? "w" : "-");
printf((int) (fileStats.st_mode & S_IXUSR) ? "x" : "-");
printf((int) (fileStats.st_mode & S_IRGRP) ? "r" : "-");
printf((int) (fileStats.st_mode & S_IWGRP) ? "w" : "-");
printf((int) (fileStats.st_mode & S_IXGRP) ? "x" : "-");
printf((int) (fileStats.st_mode & S_IROTH) ? "r" : "-");
printf((int) (fileStats.st_mode & S_IWOTH) ? "w" : "-");
printf((int) (fileStats.st_mode & S_IXOTH) ? "x\n\n" : "-\n\n");
}
至于对失败输入的更多说明,./files
和 ./files -l
都有效。 ./files
带有任何无效标志的都会按预期被捕获。但是,./files -l *any valid filepath*
总是失败。
一切都是使用gcc
in Ubuntu 14.04.5 在c9.io IDE.
中编译的
谢谢!
编辑 2:我已经尝试删除并放回文件,现在奇怪的是我没有收到错误。但是,现在它不会打印任何内容的完整文件信息。我会再解决一些问题。
编辑 3:我已修复它,但有一个例外。问题是检查标志的 if 语句不正确。显然 IDE 出了点问题。我现在收到此错误:Couldn't open MANPATH=/home/ubuntu/.nvm/versions/node/v6.11.2/share/man:/usr/local/rvm/rubies/ruby-2.4.0/share/man:/usr/local/man:/usr/local/share/man:/usr/share/man:/usr/local/rvm/man
看起来这不是代码,而是 c9 服务器在某种程度上的问题。我试过给源代码和编译后的代码文件完全权限,重新启动工作区,并重新启动 Apache2。谢谢大家所做的一切!
除了 chux 留下的评论之外,您可能会受益于重组代码以重用相似的块。您提到您已经解决了第 1 部分和第 2 部分(由 if 语句中的前两个分支表示)。因此,理论上以下 if 块会产生正确的输出。如果你简化它从而减少代码重写,你可能会受益。
if (flag == NULL)
// No flag provided, therefore only do file names.
{
dir = opendir(".");
entry = readdir(dir);
while (entry != NULL)
{
printf ("%s\n", entry->d_name);
entry = readdir(dir);
}
}
else if (strcmp(flag, "-l") == 0 && directory == NULL)
// No directory provided, but flag provided
{
dir = opendir(".");
entry = readdir(dir);
while (entry != NULL)
{
fileinfo(directory);
entry = readdir(dir);
}
}
不用这样写,你可以事先检查标志,并设置一个变量(在这种情况下more_file_info != 0
告诉我们打印,如果标志无效我们return
) .
int more_file_info = 0;
if (flag != NULL) {
if(strcmp(flag, "-l") == 0) {
more_file_info = 1;
} else {
printf("Invalid flag.\n");
return;
}
}
然后,您可以 simplify/refactor 上面的(大概可以工作的)代码如下:
void recursedirect(char* flag, char* directory)
{
DIR* dir;
struct dirent *entry;
int more_file_info = 0;
printf("Flag: %s\nDirectory: %s\n\n", flag, directory);
// Validate argument up front
if (flag != NULL) {
if(strcmp(flag, "-l") == 0) {
more_file_info = 1;
} else {
printf("Invalid flag.\n");
return;
}
}
// The 'directory' parameter only changes opendir, so we reflect that here
if(directory != NULL) {
dir = opendir(directory);
} else {
dir = opendir(".");
}
// Adding some error checking, per comment
if(dir == NULL) {
printf("Couldn't open %s\n", directory);
return;
}
// The readdir() loop is basically the same
entry = readdir(dir);
while (entry != NULL)
{
// Although we check a flag every time this loop runs,
// it makes the code easier to follow
if(more_file_info != 0) {
printf ("%s\n", entry->d_name);
} else {
fileinfo(directory);
// Or should this be:
// fileinfo(entry);
}
entry = readdir(dir);
}
}
这消除了很多重复的代码,并且有望使故障排除更加容易。另请注意,这处理了指定目录但未指定标志的情况,您可以明确检查是否需要不同的行为。希望通过更多信息,我们可以提供更合适的答案。
我在 C 语言方面经验不足,但在我的 类 中有一项作业,而且我在打开目录时遇到了一些问题。
该计划的目的是(释义):
- 如果没有提供标志或目录,则列出当前目录中的文件名。
- 如果提供标志 (-l),则列出有关每个文件的更多信息。
- 如果提供了标志和目录,则转至该目录并列出有关该目录中每个文件(或目录)的信息。没有必要通过子目录递归。
它不需要处理只获取目录但没有标志或无效目录的问题。它更像是概念验证。
我已经设法满足第 1 部分和第 2 部分的要求,但第 3 部分总是出现问题,出现分段错误。
我的代码如下:
void recursedirect(char* flag, char* directory)
{
DIR* dir;
struct dirent *entry;
printf("Flag: %s\nDirectory: %s\n\n", flag, directory);
if (flag == NULL)
// No flag provided, therefore only do file names.
{
dir = opendir(".");
entry = readdir(dir);
while (entry != NULL)
{
printf ("%s\n", entry->d_name);
entry = readdir(dir);
}
}
else if (strcmp(flag, "-l") == 0 && directory == NULL)
// No directory provided, but flag provided
{
dir = opendir(".");
entry = readdir(dir);
while (entry != NULL)
{
fileinfo(directory);
entry = readdir(dir);
}
}
else if (strcmp(flag, "-l") != 0)
{
printf("Invalid flag.\n");
}
else
// A directory is provided
{
dir = opendir(directory);
if (dir != NULL)
{
entry = readdir(dir);
while (entry != NULL)
{
fileinfo(directory);
entry = readdir(dir);
}
}
else
printf("Something went wrong. It might be an invalid filename.\n");
}
}
具体来说,最后的 else 语句给我带来了麻烦。我试过给它任何我能想到的文件路径,硬编码和其他方式,但它仍然给我带来问题。我猜这很简单,但我没有足够的经验知道它是什么。
fileinfo
是一个函数,它在给定 DIR
和 dirent
作为参数的情况下打印出文件信息。但是,错误肯定不在我能说的最好的代码中。
编辑:我犯了没有分享所有内容的错误。我的主要方法很简单。
int main (int argc, char** argv)
{
char* flag = argv[1];
char* directory = argv[2];
recursedirect(flag, directory);
}//main
它包括以下内容:
#include <dirent.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
#include <fcntl.h>
fileinfo
函数如下(稍作编辑,我意识到我不再需要给它一个参数 DIR *dir
):
void fileinfo(struct dirent *entry)
{
struct stat fileStats;
stat(entry->d_name, &fileStats);
printf("File Name: %s\n", entry->d_name);
printf("File Size: %d bytes\n", (int) fileStats.st_size);
printf("Number of Blocks: %d\n", (int) fileStats.st_blocks);
printf("Number of Links/References: %d\n", (int) fileStats.st_nlink);
printf("I-Node: %d\n", (int) fileStats.st_ino);
printf("Device ID: %d\n", (int) fileStats.st_dev);
printf("User ID: %d\n", (int) fileStats.st_uid);
printf("Group ID: %d\n", (int) fileStats.st_gid);
stat("alphabet",&fileStats);
printf("Time of Last Access: %s", ctime(&fileStats.st_atime));
printf("Time of Last Modification: %s", ctime(&fileStats.st_mtime));
printf("Time of Last Status Change: %s", ctime(&fileStats.st_ctime));
stat(entry->d_name, &fileStats);
printf("File Permissions: ");
printf((int) (S_ISDIR(fileStats.st_mode)) ? "d" : "-");
printf((int) (fileStats.st_mode & S_IRUSR) ? "r" : "-");
printf((int) (fileStats.st_mode & S_IWUSR) ? "w" : "-");
printf((int) (fileStats.st_mode & S_IXUSR) ? "x" : "-");
printf((int) (fileStats.st_mode & S_IRGRP) ? "r" : "-");
printf((int) (fileStats.st_mode & S_IWGRP) ? "w" : "-");
printf((int) (fileStats.st_mode & S_IXGRP) ? "x" : "-");
printf((int) (fileStats.st_mode & S_IROTH) ? "r" : "-");
printf((int) (fileStats.st_mode & S_IWOTH) ? "w" : "-");
printf((int) (fileStats.st_mode & S_IXOTH) ? "x\n\n" : "-\n\n");
}
至于对失败输入的更多说明,./files
和 ./files -l
都有效。 ./files
带有任何无效标志的都会按预期被捕获。但是,./files -l *any valid filepath*
总是失败。
一切都是使用gcc
in Ubuntu 14.04.5 在c9.io IDE.
谢谢!
编辑 2:我已经尝试删除并放回文件,现在奇怪的是我没有收到错误。但是,现在它不会打印任何内容的完整文件信息。我会再解决一些问题。
编辑 3:我已修复它,但有一个例外。问题是检查标志的 if 语句不正确。显然 IDE 出了点问题。我现在收到此错误:Couldn't open MANPATH=/home/ubuntu/.nvm/versions/node/v6.11.2/share/man:/usr/local/rvm/rubies/ruby-2.4.0/share/man:/usr/local/man:/usr/local/share/man:/usr/share/man:/usr/local/rvm/man
看起来这不是代码,而是 c9 服务器在某种程度上的问题。我试过给源代码和编译后的代码文件完全权限,重新启动工作区,并重新启动 Apache2。谢谢大家所做的一切!
除了 chux 留下的评论之外,您可能会受益于重组代码以重用相似的块。您提到您已经解决了第 1 部分和第 2 部分(由 if 语句中的前两个分支表示)。因此,理论上以下 if 块会产生正确的输出。如果你简化它从而减少代码重写,你可能会受益。
if (flag == NULL)
// No flag provided, therefore only do file names.
{
dir = opendir(".");
entry = readdir(dir);
while (entry != NULL)
{
printf ("%s\n", entry->d_name);
entry = readdir(dir);
}
}
else if (strcmp(flag, "-l") == 0 && directory == NULL)
// No directory provided, but flag provided
{
dir = opendir(".");
entry = readdir(dir);
while (entry != NULL)
{
fileinfo(directory);
entry = readdir(dir);
}
}
不用这样写,你可以事先检查标志,并设置一个变量(在这种情况下more_file_info != 0
告诉我们打印,如果标志无效我们return
) .
int more_file_info = 0;
if (flag != NULL) {
if(strcmp(flag, "-l") == 0) {
more_file_info = 1;
} else {
printf("Invalid flag.\n");
return;
}
}
然后,您可以 simplify/refactor 上面的(大概可以工作的)代码如下:
void recursedirect(char* flag, char* directory)
{
DIR* dir;
struct dirent *entry;
int more_file_info = 0;
printf("Flag: %s\nDirectory: %s\n\n", flag, directory);
// Validate argument up front
if (flag != NULL) {
if(strcmp(flag, "-l") == 0) {
more_file_info = 1;
} else {
printf("Invalid flag.\n");
return;
}
}
// The 'directory' parameter only changes opendir, so we reflect that here
if(directory != NULL) {
dir = opendir(directory);
} else {
dir = opendir(".");
}
// Adding some error checking, per comment
if(dir == NULL) {
printf("Couldn't open %s\n", directory);
return;
}
// The readdir() loop is basically the same
entry = readdir(dir);
while (entry != NULL)
{
// Although we check a flag every time this loop runs,
// it makes the code easier to follow
if(more_file_info != 0) {
printf ("%s\n", entry->d_name);
} else {
fileinfo(directory);
// Or should this be:
// fileinfo(entry);
}
entry = readdir(dir);
}
}
这消除了很多重复的代码,并且有望使故障排除更加容易。另请注意,这处理了指定目录但未指定标志的情况,您可以明确检查是否需要不同的行为。希望通过更多信息,我们可以提供更合适的答案。