4

私はCを初めて使用しますが、いくつかのシステムコールを試しています。

ディレクトリ内のすべてのファイルを繰り返し処理し、現在のファイル名とサイズを出力するプログラムを作成しています。プログラムにファイル名を出力させることはできますが、statシステム呼び出しを実行するとエラーが発生します。

コードの一部を次に示します。

while (dptr = readdir(dirp)) { 
            if (stat(dptr->d_name, &buf) != 0) {
                //Always does this and it does print the file name
                printf("Error on when getting size of %s \n", dptr->d_name);
            } else {
                //Never gets here
                printf("%u", buf.st_size);
              }         
}

私はこのように記述された構造体を持っています:

struct stat buf;
struct dirent *dptr;
DIR *dirp;

私が変更した場合:

if (stat(dptr->d_name, &buf) != 0)

if (stat(dptr->d_name, &buf) != [EACCES])

それでもループに入り、ファイル名を読み取れないと思いますが、エラーステートメントに問題なく出力されます。

誰かが私を正しい方向に向けることができますか?ありがとう!

アルカジー

4

4 に答える 4

4

正確なエラーを知っていれば、これらのことははるかに簡単に対処できます。試す

printf("error = %d: %s", errno, strerror(errno));
于 2011-12-15T18:33:37.750 に答える
4

まず、エラーが発生した場合、stat()は実際のエラーコードではなく-1を返します。エラーコードはerrnoに設定されます。エラーを出力する簡単な方法は、perror()を使用することです。

次に、dptr-> d_nameはファイルの相対ファイル名のみを提供し、完全なファイル名は提供しません。完全なファイル名を取得するには、相対ファイル名とディレクトリ名からファイル名を生成する必要があります。

次に例を示します。

int cwdloop(void)
{
   DIR           * dirp;
   struct stat     buff;
   struct dirent * dptr;
   char            filename[1024];
   char            dirname[1024];

   if (!(getcwd(dirname, 1024)))
   {
       perror("getcwd");
       return(1);
   };

   dirp = opendir(dirname);
   if (!(dirp))
   {
      perror("opendir()");
      return(1);
   };

   while ((dptr = readdir(dirp)))
   {
      snprintf(filename, 1024, "%s/%s", dirname, dptr->d_name);
      if (stat(filename, &buff) != 0)
      {
         perror("stat()");
         return(1);
      } else {
         printf("size: %u\n", (unsigned)buff.st_size);
      };
   };

   closedir(dirp);

   return(0);
}
于 2011-12-15T18:49:22.727 に答える
3

この種のコードに共通する問題の1つは、パス名としてファイル名だけを使用することです。dirent構造のd_nameエントリは、フルパス名を提供しませんが、ディレクトリに相対的なパス名を提供します。

これを解決するには、次のいずれかを行うことができます

  1. フルパス名を作成し、それをstatまたはに渡します

  2. chdirを呼び出す前にディレクトリに移動しstatます。

于 2011-12-15T18:48:19.497 に答える
0

質問に対する直接の答えは他の答えでカバーされています。私はこれを補足的な答えとして提供しています。システムコールをデバッグしているときstat()に、返される統計バッファを適切にフォーマットするのに次の関数が役立つ場合があります。

stat()システムコールをフォーマットし、印刷またはログに記録する方法:

static void logstat(struct stat *sp)
{
    int mode = sp->st_mode;

    if (sp->st_size > 1000000000)
        printf("  File Size:        %lluGB\n", sp->st_size / 1000000000);
    else if(sp->st_size > 1000000)
        printf("  File Size:        %lluMB\n", sp->st_size / 1000000);
    else
        printf("  File Size:        %llu bytes\n", sp->st_size);

    printf("  Number of Links:  %d\n", sp->st_nlink);
    printf("  File inode:       %d\n", sp->st_ino);
    printf("  File type:        ");
    switch (mode & S_IFMT) {
    case S_IFBLK:
        printf("BLK\n");
        break;
    case S_IFCHR:
        printf("CHR\n");
        break;
    case S_IFDIR:
        printf("DIR\n");
        break;
    case S_IFIFO:
        printf("FIFO\n");
        break;
    case S_IFLNK:
        printf("LINK\n");
        break;
    case S_IFREG:
        printf("REG\n");
        break;
    case S_IFSOCK:
        printf("SOCK\n");
        break;
    }
    printf("  File Permissions: ");
    printf( (S_ISDIR(sp->st_mode)  ? "d" : "-");
    printf( (sp->st_mode & S_IRUSR) ? "r" : "-");
    printf( (sp->st_mode & S_IWUSR) ? "w" : "-");
    printf( (sp->st_mode & S_IXUSR) ? "x" : "-");
    printf( (sp->st_mode & S_IRGRP) ? "r" : "-");
    printf( (sp->st_mode & S_IWGRP) ? "w" : "-");
    printf( (sp->st_mode & S_IXGRP) ? "x" : "-");
    printf( (sp->st_mode & S_IROTH) ? "r" : "-");
    printf( (sp->st_mode & S_IWOTH) ? "w" : "-");
    printf( (sp->st_mode & S_IXOTH) ? "x" : "-");
    printf("\n\n");
}
于 2018-09-01T21:04:22.740 に答える