簡體   English   中英

如何在C中實現unix ls -s命令?

[英]How to implement unix ls -s command in C?

我必須在C中編寫一個程序,它以塊的形式返回文件大小,就像ls -s命令一樣。 請幫忙。

我嘗試使用stat()函數(st_blksize)......我無法實現它。

我的代碼看起來像這樣

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <dirent.h>

void main(int argc, char **argv)
{
    DIR           *dp;
    struct dirent *dirp;
    struct stat    buf;

    if(argc < 2)
    {
        dp = opendir(".");
    }

    if(dp == NULL)
    {
        perror("Cannot open directory ");
        exit(2);
    }

    while ((dirp = readdir(dp)) != NULL)
    {
        printf("%s\n", dirp->d_name);
        if (stat(".", &buf))
        printf("%d ", buf.st_blksize);
    }

    closedir(dp);
    exit(0);
}

它是給出錯誤buf大小未聲明。 不知道是什么問題。

加成

謝謝你的糾正。 我包含了<sys/stat.h>頭文件。 現在它發出警告:

warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘__blksize_t’

我是C的新手,所以無法弄清楚應該是什么樣的解決方案。

您需要包含正確的標頭:

#incude <sys/stat.h>

這聲明了結構和相關的功能。

請注意, stat()在成功時返回零,因此您的測試需要更改(並且,正如@jsmchmier在注釋中指出的那樣,對stat的調用應該使用dirp->d_name而不是字符串文字"." )。 此外, st_blksize是磁盤塊的大小,而不是文件的大小 - 即st_size (以字節為單位)。

POSIX說:

off_t st_size對於常規文件,文件大小以字節為單位。 對於符號鏈接,符號鏈接中包含的路徑名的長度(以字節為單位)。

blksize_t st_blksize此對象的特定於文件系統的首選I / O塊大小。 在某些文件系統類型中,這可能因文件而異。

blkcnt_t st_blocks為此對象分配的塊數。

請注意,舊的(非常舊的)Unix版本不支持st_blksizest_blocks 我希望大多數現有版本都可以。


現在它發出警告..警告:格式'%d'需要類型'int',但參數2的類型為'__blksize_t'

__blksize_t可能__blksize_t是一個類似於size_t的unisgned整數類型。 我可能會使用一個簡單的演員:

printf("Block size = %d\n", (int)buf.st_blksize);

或者,如果您有C99可用,您可以使用<inttypes.h>來使用更大的尺寸:

printf("Block size = %" PRIu64 "\n", (uint64_t)buf.st_blksize);

在實踐中,這是過度的; 在這十年中,塊大小不太可能超過2 GB,因此在可預見的未來, int可能已足夠。

打開文件,然后stat / fstat。 struct字段st_blocks應包含所需的信息。 如果你正在處理一個目錄,請使用opendir,readdir,closedir(posix)......只是指點開始你的工作。

編輯

添加unistd.h和sys / stat.h。 然后記住,stat成功返回0,所以

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

我改變了“。” 以為“元素”的名稱,這是你想要的,我想。 另一個變化是使用st_blocks而不是st_blksize,它表示每個塊有多大(例如1024或4096或......),-s返回塊數的大小,而不是塊的大小。

代碼片段當然是不完整的:如果你傳遞一個參數,dp沒有被初始化,甚至dp == NULL都會失敗,你應該在之前使它無效:

DIR           *dp = NULL;
    struct dirent *dirp = NULL;

來自我的Mac OS X盒子上的man 2 stat

NAME
     fstat, fstat64, lstat, lstat64, stat, stat64 -- get file status  

SYNOPSIS  
     #include <sys/stat.h>  

     int
     fstat(int fildes, struct stat *buf);

注意你還沒有完成的#include <sys/stat.h> 毫無疑問, struct stat的實際布局是在那里定義的,這是你的編譯器所抱怨的。

這是手冊頁的一個方面,並不總是與初學者討論,但確實非常有用:整個unix API都記錄在其中。 哦,當你知道它應該做什么但卻不知道它叫什么時,找到一個函數並不總是最簡單的地方,但所有答案都在那里。

小心,你的代碼中的一個錯誤是dp指向垃圾,只有當argc小於2時才會初始化,但你仍然嘗試在你的while循環中使用它,你也嘗試closedir它。 如果您使用任何參數調用您的應用程序,它可能會崩潰。

要避免警告,請將行中的%d更改為%ld:printf(“%d”,buf.st_blksize);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM