C 程序不在声明的目录路径中工作,仅在当前目录中
我正在编写一个程序,从命令行中声明的目录中获取所有文件。命令行有两个参数,目录路径和一个可选标志“-s”,如果应用,该标志将按非降序显示目录信息。我已经完成了90%,但我的程序只从当前目录中吐出文件和文件信息,而不是命令行中指定的目录。如有任何建议,将不胜感激C 程序不在声明的目录路径中工作,仅在当前目录中,c,system-calls,C,System Calls,我正在编写一个程序,从命令行中声明的目录中获取所有文件。命令行有两个参数,目录路径和一个可选标志“-s”,如果应用,该标志将按非降序显示目录信息。我已经完成了90%,但我的程序只从当前目录中吐出文件和文件信息,而不是命令行中指定的目录。如有任何建议,将不胜感激 #include <stdio.h> #include <stdlib.h> #include <dirent.h> #include <unistd.h> #include <fcn
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/syscall.h>
#include <string.h>
#include <ctype.h>
int mygetFstat(char *name);
char *removeWhiteSpaces(char *str);
#define PATH 1
#define FLAG 2
#define LEN 10
#define STRLEN 54
#define MAXLEN 100
struct stat fileStat;
time_t t;
struct tm lt;
char timbuf[MAXLEN];
int main(int argc, char *argv[]){
DIR *dir;
struct dirent *ent;
FILE *ptr;
char myBuf[MAXLEN];
char filename[MAXLEN];
char finalfile[MAXLEN];
char length;
char str[MAXLEN];
char cmd[MAXLEN];
if ((dir = opendir (argv[PATH])) != NULL) {
// print all the files and directories within directory
if(argv[FLAG] != NULL){
if(strcmp(argv[FLAG], "-s") == 0){
system("ls -al | sort -k5n >> tempfile.txt");
//sprintf(finalfile, "cd %s | ls -al | sort -k5n >> tempfile.txt", (char *)argv[PATH]);
// printf("\nfinal file = %s\n", finalfile);
// system(finalfile);
if(NULL == (ptr = fopen("tempfile.txt","rw"))){
printf("\nCan't open file.\n");
exit(1);
}
while(!feof(ptr)){ // loop through every line in tempfile.txt
fgets(myBuf, MAXLEN, ptr);
if(strlen(myBuf) > LEN){ // I chose 11 here because some lines were only 10 characters
// And they were unnecessary.
length = strlen(myBuf); // Grabs length of entire line from ptr
strncpy(filename, myBuf + STRLEN, length); // the file names start at bit position 54,
if((filename[0] == '.') && (filename[1] != '.') && (strlen(filename) != 2)){
removeWhiteSpaces(filename);
mygetFstat(filename);
}
}
}
system("rm tempfile.txt");
exit(1);
}else{
printf("Error: Flag not recognized.\n");
return 0;
}
}else{
while((ent = readdir(dir)) != NULL){
if((ent->d_name[0] == '.') && (ent->d_name[1] != '.') && (strlen(ent->d_name) != 1))
mygetFstat(ent->d_name);
}
closedir (dir);
}
} else {
// could not open directory
printf("No such File or Directory.\n");
return EXIT_FAILURE;
}
}
int mygetFstat(char *name)
{
// Function for finding info about files.
int file = 0;
if((file = open(name,O_RDONLY)) < -1)
return 1;
if(fstat(file,&fileStat) < 0)
return 1;
printf("Information for %s\n",name);
printf("---------------------------\n");
printf("File Size: \t\t%d bytes\n",fileStat.st_size);
// Adjusts time to display date. Not just seconds from epoch
t = fileStat.st_mtime;
localtime_r(&t, <);
strftime(timbuf, sizeof(timbuf), "%c", <);
printf("Date Last Modified: \t%s\n",timbuf);
printf("\n");
//return 0;
}
char *removeWhiteSpaces(char *str){ //removes white spaces from input
char *end;
while(isspace(*str)) str++;
if(*str == 0)
return str;
end = str + strlen(str)-1;
while(end > str && isspace(*end)) end--;
*(end+1) = 0;
return str;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int mygetFstat(字符*名称);
char*removewitespaces(char*str);
#定义路径1
#定义标志2
#定义LEN 10
#定义STRLEN 54
#定义MAXLEN 100
struct stat fileStat;
时间;
struct-tm-lt;
char timbuf[MAXLEN];
int main(int argc,char*argv[]){
DIR*DIR;
结构导向;
文件*ptr;
char myBuf[MAXLEN];
字符文件名[MAXLEN];
字符最终文件[MAXLEN];
字符长度;
char-str[MAXLEN];
char cmd[MAXLEN];
if((dir=opendir(argv[PATH])!=NULL){
//打印目录中的所有文件和目录
如果(argv[FLAG]!=NULL){
如果(strcmp(argv[FLAG],“-s”)==0){
系统(“ls-al | sort-k5n>>tempfile.txt”);
//sprintf(最终文件,“cd%s | ls-al | sort-k5n>>tempfile.txt”,(char*)argv[PATH]);
//printf(“\n最终文件=%s\n”,最终文件);
//系统(最终文件);
if(NULL==(ptr=fopen(“tempfile.txt”、“rw”)){
printf(“\n无法打开文件。\n”);
出口(1);
}
而(!feof(ptr)){//则遍历tempfile.txt中的每一行
fgets(myBuf、MAXLEN、ptr);
如果(strlen(myBuf)>LEN){//我在这里选择了11,因为有些行只有10个字符
//它们是不必要的。
length=strlen(myBuf);//从ptr获取整行的长度
strncpy(filename,myBuf+STRLEN,length);//文件名从位54开始,
如果((文件名[0]='。)&&(文件名[1]!='。)&&(strlen(文件名)!=2)){
删除空白(文件名);
mygetFstat(文件名);
}
}
}
系统(“rm tempfile.txt”);
出口(1);
}否则{
printf(“错误:无法识别标志。\n”);
返回0;
}
}否则{
while((ent=readdir(dir))!=NULL){
如果((ent->d_名称[0]='.)&(ent->d_名称[1]!='.)&&(strlen(ent->d_名称)!=1))
mygetFstat(ent->d_名称);
}
closedir(dir);
}
}否则{
//无法打开目录
printf(“没有这样的文件或目录。\n”);
返回退出失败;
}
}
int mygetFstat(字符*名称)
{
//用于查找有关文件的信息的函数。
int file=0;
如果((文件=打开(名称,仅限))<-1)
返回1;
if(fstat(file,&fileStat)<0)
返回1;
printf(“用于%s\n的信息”,名称);
printf(“------------------------------------\n”);
printf(“文件大小:\t\t%d字节\n”,fileStat.st\u Size);
//调整显示日期的时间。而不仅仅是从历元开始的秒数
t=fileStat.st_mtime;
本地时间(r&t,<);
strftime(timbuf,sizeof(timbuf),%c',<);
printf(“上次修改日期:\t%s\n”,timbuf);
printf(“\n”);
//返回0;
}
char*removeWhiteSpaces(char*str){//从输入中删除空白
字符*结束;
而(isspace(*str))str++;
如果(*str==0)
返回str;
end=str+strlen(str)-1;
而(end>str&&isspace(*end))end--;
*(结束+1)=0;
返回str;
}
ent->d_name
仅包含该目录中条目的名称。它不包括条目的完整路径
如果第一个参数是“folder1”,并且该目录中有文件“file-1.txt”和“file-2.txt”,则ent->d_name
将是“file-1.txt”和“file-2.txt”。您需要将“folder1/file-1.txt”传递到mygetFstat()
,而不仅仅是“file-1.txt”
您应该将while
循环更改为:
while((ent = readdir(dir)) != NULL){
if((ent->d_name[0] == '.') && (ent->d_name[1] != '.') && (strlen(ent->d_name) != 1))
{
strcpy(filename, argv[PATH]);
strcat(filename, "/");
strcat(filename, ent->d_name);
mygetFstat(filename);
}
}
while((ent = readdir(dir)) != NULL){
if ( is_dot_or_dot_dot(ent->d_name) )
{
continue;
}
strcpy(filename, argv[PATH]);
strcat(filename, "/");
strcat(filename, ent->d_name);
mygetFstat(filename);
}
更新
我将添加一个函数
int is_dot_or_dot_dot(char const* entryName)
{
return (strcmp(entryName, ".") == 0) || (strcmp(entryName, "..") == 0);
}
并将while
循环中的代码更改为:
while((ent = readdir(dir)) != NULL){
if((ent->d_name[0] == '.') && (ent->d_name[1] != '.') && (strlen(ent->d_name) != 1))
{
strcpy(filename, argv[PATH]);
strcat(filename, "/");
strcat(filename, ent->d_name);
mygetFstat(filename);
}
}
while((ent = readdir(dir)) != NULL){
if ( is_dot_or_dot_dot(ent->d_name) )
{
continue;
}
strcpy(filename, argv[PATH]);
strcat(filename, "/");
strcat(filename, ent->d_name);
mygetFstat(filename);
}
保留代码,在打开目录后立即执行chdir:
if ((dir = opendir (argv[PATH])) != NULL) {
// print all the files and directories within directory
// Change the working directory to the one given.
if (chdir(argv[PATH]) == -1) {
perror(argv[PATH]); exit(1);
}
另外,我建议使用perror,但你必须包括errno.h
对其余代码的改进
system("ls -al | sort -k5n >> tempfile.txt");
虽然您可以这样做,但将其插入到链表中并在插入时对其进行排序将是一种更快的方法。但如果您想保留它,请参见下面的改进
这个项目的全部要点是使用系统调用
feof不可靠,请使用
while( fgets (myBuf, MAXLEN, ptr)!=NULL ){
我理解你的逻辑,我感谢你的回答。但我无法让您的代码段正常工作。当我运行它时,它保持堆芯转储。我是个白痴。忽略该评论^^^感谢您的输入此操作非常有效@用户3600601很高兴它起作用了。我仍然对
if
语句感到困惑。你是想说忽略
和。
?是的!我不想要当前目录(.)和上一个目录(..)的信息,所以我用if排除这些信息。此外,如果您在这一行有任何输入:system(“ls-al | sort-k5n>>tempfile.txt”);我不太擅长unix命令,这只返回当前目录中的文件,而不是目录路径。再多给点建议就好了。非常感谢。