我必须在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的新手,所以无法弄清楚应该是什么样的解决方案。
答案 0 :(得分:5)
您需要包含正确的标题:
#incude <sys/stat.h>
宣告结构和相关功能。
请注意stat()
成功时返回零,因此您的测试需要更改(并且,正如@jsmchmier在注释中指出的那样,对stat的调用应该使用dirp->d_name
而不是字符串文字{ {1}})。此外,"."
是磁盘块的大小,而不是文件的大小 - st_blksize
(以字节为单位)。
POSIX说:
st_size
对于常规文件,文件大小以字节为单位。 对于符号链接,以字节为单位的长度 路径名包含在符号链接中。
off_t st_size
特定于文件系统的首选I / O块大小 对于这个对象。在某些文件系统类型中,这个 可能因文件而异。
blksize_t st_blksize
为此对象分配的块数。
请注意,旧的(非常旧的)Unix版本不支持blkcnt_t st_blocks
或st_blksize
。我希望大多数当前版本都可以。
现在它发出警告..警告:格式'%d'需要类型'int',但参数2的类型为'__blksize_t'
st_blocks
可能是与__blksize_t
类似的未分解整数类型。我可能会使用一个简单的演员:
size_t
或者,如果您有C99可用,则可以使用printf("Block size = %d\n", (int)buf.st_blksize);
中的设施来使用更大的尺寸:
<inttypes.h>
在实践中,这是过度的;这个十年的块大小不太可能超过2 GB,因此在可预见的未来,printf("Block size = %" PRIu64 "\n", (uint64_t)buf.st_blksize);
可能已经足够了。
答案 1 :(得分:1)
打开文件,然后使用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;
答案 2 :(得分:1)
从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都记录在其中。哦,当你知道它应该做什么但却不知道它叫什么时,找到一个函数并不总是最简单的地方,但所有答案都在那里。
答案 3 :(得分:1)
小心,代码中的一个错误是dp
指向垃圾,只有在argc
小于2时才会初始化,但您仍尝试在while
循环中使用它你也尝试closedir
它。如果您使用任何参数调用您的应用程序,它可能会崩溃。
答案 4 :(得分:0)
要避免警告,请将行中的%d更改为%ld:printf(“%d”,buf.st_blksize);