问题描述
我必须做什么
我必须从一个目录开始,在所有目录之一中找到一个文件,该目录以输入中传递的目录为根目录。
类似于 shell 命令 find
。
输入/输出
输入:
./myfind /home/claudio/Scrivania file.txt
我在输出、绝对路径和最后修改日期 ecc 中需要这样的东西:
/home/claudio/Scrivania/SistemiOperativi/file.txt Tue Mar 30 19:51:54 2021
我的代码 它不打印任何东西。
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <errno.h>
#if !defined(NAME_MAX)
#define NAME_MAX 256
#endif
void find(const char* passed_dir_name,const char* passed_file_name) {
if (chdir(passed_dir_name) == -1) {
perror("Fatal error CHANGING DIRECTORY");
exit(EXIT_FAILURE);
}
DIR* current_directory;
if ((current_directory = opendir(".")) == NULL) {
perror("Fatal error opening CURRENT WORKING DIRECTORY");
exit(EXIT_FAILURE);
}
char* buf;
if ((buf = calloc(NAME_MAX,sizeof(char))) == NULL) {
perror("Fatal error ALLOCATING MEMORY");
exit(EXIT_FAILURE);
}
struct dirent* dir;
while ((dir = readdir(current_directory)) != NULL) {
struct stat statbuf;
stat(dir->d_name,&statbuf);
if (S_ISDIR(statbuf.st_mode)) {
if (strncmp(dir->d_name,".",1) != 0 && strncmp(dir->d_name,"..",2) != 0) {
find(dir->d_name,passed_file_name);
}
} else {
if (strncmp(dir->d_name,passed_file_name,strlen(passed_file_name) == 0)) {
if (getcwd(buf,NAME_MAX) == NULL) {
perror("Fatal error");
exit(EXIT_FAILURE);
}
fprintf(stdout,"%s/%s %s",buf,dir->d_name,ctime(&statbuf.st_mtime));
}
}
}
if (closedir(current_directory) == -1) {
perror("Fatal error CLOSING CURRENT WORKING DIRECTORY");
exit(EXIT_FAILURE);
}
chdir("..");
free(buf);
}
int main(int argc,char** argv) {
if (argc != 3) {
fprintf(stderr,"ERROR: RUn as ./myfind directory\n");
exit(EXIT_FAILURE);
}
const char* dir = argv[1];
const char* file = argv[2];
struct stat statbuf;
stat(dir,&statbuf);
if(!S_ISDIR(statbuf.st_mode)) {
fprintf(stderr,"Fatal error: %s IS NOT A DIRECTORY\n",dir);
exit(EXIT_FAILURE);
}
find(dir,file);
exit(EXIT_SUCCESS);
}
解决方法
你的括号有误:
if (strncmp(dir->d_name,passed_file_name,strlen(passed_file_name) == 0))
你需要写:
if (strncmp(dir->d_name,strlen(passed_file_name)) == 0)
由于 strncmp(x,y,0)
将始终返回 0,因此永远不会满足条件。
但请注意,在这里使用 strncmp
根本没有意义。 strncmp
仅在您不知道您的条目之一是空终止字符串时才需要。您可以保证 d_name
以空字符结尾,如果 passed_file_name
不是,那么 strlen
将会有问题。你也可以直接写strcmp(dir->d_name,passed_file_name)
。