为什么 stat return 结果错误?
Why does stat return wrong result?
我想使用 stat
检查给定的参数是否是目录。该程序有 2 个参数:当第一个参数不是目录或它不存在时,代码可以正常工作。
但是当第一个参数是一个目录并且存在,而第二个参数不存在时,程序说它们都存在——错误的结果。我想知道为什么它不起作用。
#include <stdio.h>
#include <sys/stat.h>
int main(int n, char **argv)
{
char *dir_1=argv[1], *dir_2=argv[2];
if (is_dir(dir_1) == 0)
printf("Directory %s exists.\n", dir_1);
else
printf("Directory %s does not exist.\n", dir_1);
if (is_dir(dir_2) == 0)
printf("Directory %s exists.\n", dir_2);
else
printf("Directory %s does not exist.\n", dir_2);
}
int is_dir(char *file)
{
struct stat file_stat;
stat(file, &file_stat);
return( (S_ISDIR(file_stat.st_mode)) ? 0 : -1);
}
如果文件不存在,stat
自己returns -1
,并设置errno
为ENOENT
。但是由于第一个目录存在并且是一个目录,所以struct stat
填充的是一个目录的信息;这恰好位于堆栈中第二次 stat
调用的完全相同位置。第二个 stat
因 errno
ENOENT
失败,但随后 is_dir
解释了第一次调用留下的值。
is_dir
更正确的实现可能是:
int is_dir(char *file)
{
struct stat file_stat;
// if an error occurs, we return 0 for false
if (stat(file, &file_stat) < 0) {
return 0;
}
// otherwise we return whatever the S_ISDIR returns
return S_ISDIR(file_stat.st_mode);
}
请注意,我也更改了 return 值;诸如 is_dir
之类的函数应 return 一个布尔值,在函数名称说明真实事实的情况下为真(非零),否则为零。
你会像这样使用它:
if (is_dir(dir_1)) {
printf("Directory %s exists.\n", dir_1);
}
else {
printf("Directory %s does not exist.\n", dir_1);
}
if (is_dir(dir_2)) {
printf("Directory %s exists.\n", dir_2);
}
else {
printf("Directory %s does not exist.\n", dir_2);
}
请注意,本例中的 return 值 0 并不意味着一定不存在具有该名称的目录; stat
系统调用也可能由于权限不足等原因而失败;扩展逻辑(解释 errno
的值)超出了这个答案的范围。
这个答案是一个又一个被采纳的。 S_ISDIR
在 MSVC 中不存在,而是有 _S_IFDIR
。替换后,编译器通知 is_dir()
不是 return 值。原因是 _S_IFDIR
是掩码,而不是函数。因此,在对代码进行了一些调整之后,我得到了它。
#include <stdio.h>
#include <sys/stat.h>
int is_dir(char *file)
{
struct stat file_stat;
if (stat(file, &file_stat) == 0) // check it worked
return file_stat.st_mode & _S_IFDIR; // it's a status mask
return 0;
}
int main(int argc, char **argv) // conventional ids
{
char *dir_1, *dir_2;
if (argc < 3) return 0; // check silliness
dir_1=argv[1];
dir_2=argv[2];
if (is_dir(dir_1)) // reversed the logic
printf("%s is a Directory.\n", dir_1);
else
printf("%s is not a Directory.\n", dir_1); // better text
if (is_dir(dir_2))
printf("%s is a Directory.\n", dir_2);
else
printf("%s is not a Directory.\n", dir_2);
return 0;
}
程序输出:
>test test.c wtest
test.c is not a Directory.
wtest is a Directory.
反过来:
>test wtest test.c
wtest is a Directory.
test.c is not a Directory.
我想使用 stat
检查给定的参数是否是目录。该程序有 2 个参数:当第一个参数不是目录或它不存在时,代码可以正常工作。
但是当第一个参数是一个目录并且存在,而第二个参数不存在时,程序说它们都存在——错误的结果。我想知道为什么它不起作用。
#include <stdio.h>
#include <sys/stat.h>
int main(int n, char **argv)
{
char *dir_1=argv[1], *dir_2=argv[2];
if (is_dir(dir_1) == 0)
printf("Directory %s exists.\n", dir_1);
else
printf("Directory %s does not exist.\n", dir_1);
if (is_dir(dir_2) == 0)
printf("Directory %s exists.\n", dir_2);
else
printf("Directory %s does not exist.\n", dir_2);
}
int is_dir(char *file)
{
struct stat file_stat;
stat(file, &file_stat);
return( (S_ISDIR(file_stat.st_mode)) ? 0 : -1);
}
如果文件不存在,stat
自己returns -1
,并设置errno
为ENOENT
。但是由于第一个目录存在并且是一个目录,所以struct stat
填充的是一个目录的信息;这恰好位于堆栈中第二次 stat
调用的完全相同位置。第二个 stat
因 errno
ENOENT
失败,但随后 is_dir
解释了第一次调用留下的值。
is_dir
更正确的实现可能是:
int is_dir(char *file)
{
struct stat file_stat;
// if an error occurs, we return 0 for false
if (stat(file, &file_stat) < 0) {
return 0;
}
// otherwise we return whatever the S_ISDIR returns
return S_ISDIR(file_stat.st_mode);
}
请注意,我也更改了 return 值;诸如 is_dir
之类的函数应 return 一个布尔值,在函数名称说明真实事实的情况下为真(非零),否则为零。
你会像这样使用它:
if (is_dir(dir_1)) {
printf("Directory %s exists.\n", dir_1);
}
else {
printf("Directory %s does not exist.\n", dir_1);
}
if (is_dir(dir_2)) {
printf("Directory %s exists.\n", dir_2);
}
else {
printf("Directory %s does not exist.\n", dir_2);
}
请注意,本例中的 return 值 0 并不意味着一定不存在具有该名称的目录; stat
系统调用也可能由于权限不足等原因而失败;扩展逻辑(解释 errno
的值)超出了这个答案的范围。
这个答案是一个又一个被采纳的。 S_ISDIR
在 MSVC 中不存在,而是有 _S_IFDIR
。替换后,编译器通知 is_dir()
不是 return 值。原因是 _S_IFDIR
是掩码,而不是函数。因此,在对代码进行了一些调整之后,我得到了它。
#include <stdio.h>
#include <sys/stat.h>
int is_dir(char *file)
{
struct stat file_stat;
if (stat(file, &file_stat) == 0) // check it worked
return file_stat.st_mode & _S_IFDIR; // it's a status mask
return 0;
}
int main(int argc, char **argv) // conventional ids
{
char *dir_1, *dir_2;
if (argc < 3) return 0; // check silliness
dir_1=argv[1];
dir_2=argv[2];
if (is_dir(dir_1)) // reversed the logic
printf("%s is a Directory.\n", dir_1);
else
printf("%s is not a Directory.\n", dir_1); // better text
if (is_dir(dir_2))
printf("%s is a Directory.\n", dir_2);
else
printf("%s is not a Directory.\n", dir_2);
return 0;
}
程序输出:
>test test.c wtest
test.c is not a Directory.
wtest is a Directory.
反过来:
>test wtest test.c
wtest is a Directory.
test.c is not a Directory.