程序不在声明的目录路径中工作,仅在当前目录中

时间:2014-05-04 04:08:11

标签: c system-calls

我正在编写一个程序,该程序从命令行中声明的目录中获取所有文件。命令行有2个参数,目录路径和可选标志" -s"如果应用,它以非递减顺序吐出目录信息。我完成了90%,但我的程序只从当前目录中吐出文件和文件信息,而不是命令行中指定的目录。任何建议将不胜感激

#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, &lt);
    strftime(timbuf, sizeof(timbuf), "%c", &lt);
    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;
}

2 个答案:

答案 0 :(得分:0)

ent->d_name仅包含该目录中条目的名称。它不包括条目的完整路径。

如果第一个参数是“folder1”并且该目录中有文件“file-1.txt”和“file-2.txt”,ent->d_name将是“file-1.txt”和“文件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);
   }
}

<强>更新

我会添加一个功能

int is_dot_or_dot_dot(char const* entryName)
{
   return (strcmp(entryName, ".") == 0) || (strcmp(entryName, "..") == 0);
}

并将while循环内的代码更改为:

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);
}

答案 1 :(得分:0)

保留代码,在打开目录后立即执行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);
     }

P.S我建议使用perror,但你必须包含errno.h。

改进其余代码。

       system("ls -al | sort -k5n >> tempfile.txt");

虽然你可以这样做,但是在插入链接列表时将它插入链接列表是一种更快捷的方式。但是如果你想保持它,请看下面的改进。

这个项目的重点是使用系统调用。参见http://www.albany.edu/~csi402/pdfs/lect_10.pdf

        while(!feof(ptr)){             // loop through every line in tempfile.txt
          fgets(myBuf, MAXLEN, ptr);

feof不可靠,请使用

       while( fgets (myBuf, MAXLEN, ptr)!=NULL ){