S_ISREG 返回 0

MrA*_*eiL 2 c file-io posix

所以我想测试给定的文件是否正常。

#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h> 
#include <unistd.h>
#include <string.h>
#include <errno.h>

int main(int argc, char **argv)
{
    // Input check.
    if (argc != 2) {
        fprintf(stdout,"Format: %s <filename.txt>\n", argv[0]);
        return -1;
    }
    // Make sure the file is a regular file.
    int fd;
    if ((fd = open(argv[1], O_RDONLY) == -1)) {
        fprintf(stdout, "%s", strerror(errno));
        return -1;
    }
    struct stat st;
    if ((fstat(fd, &st) == -1)) {
        fprintf(stdout, "%s\n", strerror(errno));
        return -1;
    }
    if (!(S_ISREG(st.st_mode))) {
        fprintf(stdout, "Error, invalid file\n");
        return -1;
    }
    close(fd);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我跑: .\a in.txt

我不知道到底发生了什么,但是当我尝试测试文件是否正常(最后一个 if 语句)时,它失败了。我测试了 fstat 是否失败,但没有。

dbu*_*ush 5

这是问题所在:

if ((fd = open(argv[1], O_RDONLY) == -1)) {
Run Code Online (Sandbox Code Playgroud)

相等运算符的==优先级高于赋值运算符=。所以上面的解析为:

if (fd = (open(argv[1], O_RDONLY) == -1)) {
Run Code Online (Sandbox Code Playgroud)

这将分配给fd比较的结果,该结果将为 0 或 1。这些值都恰好是 stdin 和 stdout 的有效打开文件描述符,因此fstat调用成功并为您提供这些流之一的状态。

您需要先调整括号以进行分配:

if ((fd = open(argv[1], O_RDONLY)) == -1) {
Run Code Online (Sandbox Code Playgroud)

此外,您似乎还有其他if语句,其中包含可以删除的一组冗余括号。您想避免这种情况,因为那些额外的括号可以使有关您所做的事情的警告静音。