我是Unix编程和C的初学者,我对struct stat
及其字段st_mode
有两个问题:
如下所示访问st_mode
字段时,会返回什么类型的数字(八进制,十进制等)?
struct stat file;
stat( someFilePath, &file);
printf("%d", file.st_mode );
我认为数字是八进制的,但是当我运行此代码时,我得到了值33188
。什么是基础?
st_mode
编码一个16位二进制数,表示文件类型和文件权限。如何从上面的输出中获取16位数字(特别是当它看起来不是八进制时)。 16位数字的哪些部分对哪些信息进行编码?感谢您的帮助。
答案 0 :(得分:5)
我认为你在这里混合概念。
在内存中,整数值始终为二进制,我们称之为原生格式。 st_mode
的类型为mode_t
,该类型是未指定的整数类型,可能为int
。
base 的概念,即十进制,八进制或十六进制,仅在将本机格式的内存中的数字转换为文本表示(或从文本转换为本机)时才有用。
例如:
int x = 42;
将数字42指定给整数变量。由于源代码是文本,42
作为文本输入,我们知道它是十进制值(无前缀)。但请注意我们如何不为变量指定基数:它没有一个。
这个其他代码:
int x = 0x2A;
完全相同。它使用十六进制常量42
而不是十进制常量0x2A
,但这是相同的,并且x
在两种情况下都具有相同的值。同样地:
int x = 052;
也是等价的,但是具有八进制常量。
现在你的代码。当你这样做时:
printf("%d", file.st_mode);
33188
告诉程序将该变量的值输出为十进制数。请记住printf
将数字从原生格式转换为文本,因此该文本的基础很重要。如果您希望将值视为八进制,请写下:
printf("%o", file.st_mode);
100644
或以十六进制:
printf("%x", file.st_mode);
81A4
关于八进制的好处是它每个八进制数字恰好代表3位(十六进制每位数为4位),所以通过一些练习,你可以看到没有计算的位。
例如,您的st_mode
为十进制33188
或八进制为0100644
。小数告诉我什么,但是八进制确实意味着什么,因为我记得最后9位(3个八进制数字)是权限:所有者为3位,组为3位,其他为3位。所以:
* Owner: 6 that is rw-
* Group: 4 that is r--
* Other: 4 that is r--
顺便说一句,最后一个是这个常数:
#define S_IFREG 0100000
这只意味着它是一个普通文件。
答案 1 :(得分:0)
该数字是一个值。在printf()
中,您可以使用"%d"
以十进制格式打印(如您所做),或使用"%o"
(或"%lo"
)代替,以八进制形式打印
检查man 2 stat有关每种信息的表示方式。然后,您可以使用位掩码来提取所需的信息。有一个例子在手册页中展示了它。
答案 2 :(得分:0)
您将其打印为十进制,因此您获得了小数。如果你把它打印成八进制,你就得到了八进制;同上十六进制。
以八进制打印时,st_mode
字段最容易被理解。
printf("mode = %07o\n", file.st_mode);
最后三位是chmod
等熟悉的权限(例如644)。右边的第四位通常为0,但对于set-UID,set-GID或sticky,它将为非零位文件或目录。其余数字标识文件的类型。
您可以使用<sys/stat.h>
中的宏来剖析信息。