c S_ISDIR和S_ISREG不工作

c S_ISDIR和S_ISREG不工作,c,linux,file-type,C,Linux,File Type,我需要在linux中使用C制作一个应用程序,我需要输入一个文件夹路径并将所有文件和子目录复制到一个新文件夹中。 问题是,当我尝试检查路径是否指向文件夹或文件时,程序总是像文件夹一样选择路径,即使它是文件。我不知道我做错了什么。代码如下: #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/types.h>

我需要在linux中使用C制作一个应用程序,我需要输入一个文件夹路径并将所有文件和子目录复制到一个新文件夹中。 问题是,当我尝试检查路径是否指向文件夹或文件时,程序总是像文件夹一样选择路径,即使它是文件。我不知道我做错了什么。代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <assert.h>

int main()
{
    CopyFile("test3","test4");
    return (0);
}

void mkdirRecursive(const char *path, mode_t mode) {
    char opath[PATH_MAX];
    char *p;
    size_t len;

    strncpy(opath, path, sizeof(opath));
    opath[sizeof(opath) - 1] = '\0';
    len = strlen(opath);
    if (len == 0)
        return;
    else if (opath[len - 1] == '/')
        opath[len - 1] = '\0';
    for(p = opath; *p; p++)
        if (*p == '/') {
            *p = '\0';
            if (access(opath, F_OK))
                mkdir(opath, mode);
            *p = '/';
        }
    if (access(opath, F_OK))         
        mkdir(opath, mode);
}

void CopyFile(char* NumeFisOld, char* NumeFisNew)
{


    DIR *dp;
    struct dirent *dirp;
    struct stat info;
    char OldDirPath[255];
    char NewDirPath[255];
    stat(NumeFisOld,&info);
    int status = stat (NumeFisOld, &info);
    if (status != 0) 
    {
        fprintf (stderr, "Error, errno = %d\n", errno);
        perror("stat error: ");
        return;
    }
    fprintf (stderr, "Error, errno = %d\n", errno);
    perror("stat error: ");
    if(S_ISREG(info.st_mode))
    {
        printf("File: File location: %s \n",NumeFisOld);
        printf("File: New file location: %s \n",NumeFisNew);
        char buffer[65];
        int fhRead;
        int fhWrite;
        unsigned int nbytes=65;
        int bytesread;
        int byteswritten;
        if((fhRead=open(NumeFisOld, O_RDONLY)) ==-1)
        {
            perror("Eroare la deschiderea fisierului");
            exit(1);
        }

        if((bytesread=read(fhRead,buffer,nbytes))<=0)
            perror("Probleme la citirea fisierului");
        else
            printf("Citeste %u bytes din fisier\n", bytesread);

        close(fhRead);
        if((fhWrite=open(NumeFisNew,O_WRONLY | O_CREAT,S_IREAD | S_IWRITE)) !=-1) 
        {
            if((byteswritten=write(fhWrite, buffer, sizeof(buffer))) == -1)
                perror("Eroare la scriere");
            else
                printf("A scris %u bytes in fisier\n",byteswritten);
            close(fhWrite);
        }

    }
    else if(S_ISDIR(info.st_mode))
    {
        printf("Folder: File location: %s \n",NumeFisOld);
        printf("Folder: New file location: %s \n",NumeFisNew);
        dp=opendir(NumeFisOld);
        while((dirp=readdir(dp)) != NULL)
        {

            strcpy(OldDirPath, NumeFisOld);
            strcat(OldDirPath,"/");
            strcat(OldDirPath,dirp->d_name);
            strcpy(NewDirPath, NumeFisNew);
            strcat(NewDirPath, "/");
            strcat(NewDirPath,dirp->d_name);
            DIR* dir = opendir(NewDirPath);
            if(dirp->d_name[0]!='.') 
            {
                if (dir)
                {
                    /* Directonry exists. */
                    CopyFile (OldDirPath,NewDirPath);
                    printf("Directorul %s exista deja \n",NewDirPath);
                    closedir(dir);
                }
                else if (ENOENT == errno)
                {

                    printf("Directorul %s nu exista \n",NewDirPath);
                    mkdirRecursive(NewDirPath,0755);
                    CopyFile (OldDirPath,NewDirPath);
                    /* Directory does not exist. */
                }
                else
                {
                    printf("Directorul %s nu s-a putut deschide \n",NewDirPath);
                    /* opendir() failed for some other reason. */
                }
            }

        }


    }

}

如果它前面有文件,则表示它是从If(S_ISREG)使用的,如果它有文件夹,则表示它是从If(S_ISDIR)使用的。所以,至少现在它认识到test1和test2是文件,但它仍然将它们复制为文件夹。

您必须切换控制语句:首先查看它是否是文件,然后检查它是否是目录

if (S_ISREG (info.st_mode)) 
{
    printf ("It's a file\n");
}
else if (S_ISDIR (info.st_mode)) 
{
    printf ("It's a dir\n");
}
此外,您应该注意stat返回值

int status = stat (NumeFisOld, &info);
if (status != 0) 
{
    fprintf (stderr, "Error, errno = %d\n", errno);
    perror("stat error: ");
    return;
}

您应该检查stat()-调用是否成功;如果没有,您的结构中会有一些任意数据,宏
S_ISDIR()
可能会返回true。首先,正确缩进代码。抱歉,我现在用缩进的方式修改了代码。我只是按照您告诉我的做了,我先检查了它是否是文件,然后是目录,在执行此操作之前,我检查了状态,它没有进入if,如果我在stderr之外检查,它说它是0,它成功了。但是,同样的问题仍在发生。它复制所有文件夹,但不复制文件。所以我想传递给函数的参数中有一些东西,你能举个例子吗?此外,应该移动函数顶部的opendir调用。因此,我有一个名为test3的文件夹。在其中,我有一个名为test1的文件和另一个名为test4的文件夹,在test4中,我有一个名为test2的文件。我想创建一个名为test4的文件夹,在其中复制test3中的所有文件和目录。我不确定这是否是您所说的示例的意思,我的意思是:将传递给函数的真正字符串发布。使用printf来读取它的真实经过。不管怎样,我设法修复了它。我刚刚在文件分支中添加了一个带有.txt的strcat,现在它可以工作了,谢谢大家的帮助。
int status = stat (NumeFisOld, &info);
if (status != 0) 
{
    fprintf (stderr, "Error, errno = %d\n", errno);
    perror("stat error: ");
    return;
}