Как использовать macros S_ISREG () и S_ISDIR () POSIX?

Это программа C, которую я написал, чтобы рекурсивно перемещаться и выводить каталоги и обычные файлы. Он компилируется и работает отлично на моей машине Linux. Но в Solaris dit->d_type == 8 и другие аналогичные не работают, потому что нет поля d_type . Ответ, который я прочитал этой проблеме, заключается в использовании S_ISREG() и S_ISDIR() , но они не работают полностью, как у меня есть в моем коде в настоящее время. Я прокомментировал строки, которые работают на моей машине Linux.

 #include  #include  #include  #include  #include  #include  #include  #include  void helper(DIR *, struct dirent *, struct stat, char *, int, char **); void dircheck(DIR *, struct dirent *, struct stat, char *, int, char **); int main(int argc, char *argv[]){ DIR *dip; struct dirent *dit; struct stat statbuf; char currentPath[FILENAME_MAX]; int depth = 0; /*Used to correctly space output*/ /*Open Current Directory*/ if((dip = opendir(".")) == NULL) return errno; /*Store Current Working Directory in currentPath*/ if((getcwd(currentPath, FILENAME_MAX)) == NULL) return errno; /*Read all items in directory*/ while((dit = readdir(dip)) != NULL){ /*Skips . and ..*/ if(strcmp(dit->d_name, ".") == 0 || strcmp(dit->d_name, "..") == 0) continue; if(stat(currentPath, &statbuf) == -1){ perror("stat"); return errno; } /*Checks if current item is of the type file (type 8) and no command line arguments if(dit->d_type == 8 && argv[1] == NULL)*/ if(S_ISREG(statbuf.st_mode) && argv[1] == NULL) printf("%s (%d bytes)\n", dit->d_name, (int)statbuf.st_size); /*If a command line argument is given, checks for filename match if(dit->d_type == 8 && argv[1] != NULL)*/ if(S_ISREG(statbuf.st_mode) && argv[1] != NULL) if(strcmp(dit->d_name, argv[1]) == 0) printf("%s (%d bytes)\n", dit->d_name, (int)statbuf.st_size); /*Checks if current item is of the type directory (type 4) if(dit->d_type == 4)*/ if(S_ISDIR(statbuf.st_mode)) dircheck(dip, dit, statbuf, currentPath, depth, argv); } closedir(dip); return 0; } /*Recursively called helper function*/ void helper(DIR *dip, struct dirent *dit, struct stat statbuf, char currentPath[FILENAME_MAX], int depth, char *argv[]){ int i = 0; if((dip = opendir(currentPath)) == NULL) printf("Error: Failed to open Directory ==> %s\n", currentPath); while((dit = readdir(dip)) != NULL){ if(strcmp(dit->d_name, ".") == 0 || strcmp(dit->d_name, "..") == 0) continue; stat(currentPath, &statbuf); /*if(dit->d_type == 8 && argv[1] == NULL){*/ if(S_ISREG(statbuf.st_mode) && argv[1] == NULL){ for(i = 0; i d_name, (int)statbuf.st_size); } /*if(dit->d_type == 8 && argv[1] != NULL){*/ if(S_ISREG(statbuf.st_mode) && argv[1] != NULL){ if(strcmp(dit->d_name, argv[1]) == 0){ for(i = 0; i d_name, (int)statbuf.st_size); } } /*if(dit->d_type == 4)*/ if(S_ISDIR(statbuf.st_mode)) dircheck(dip, dit, statbuf, currentPath, depth, argv); } } void dircheck(DIR *dip, struct dirent *dit, struct stat statbuf, char currentPath[FILENAME_MAX], int depth, char *argv[]){ int i = 0; strcat(currentPath, "/"); strcat(currentPath, dit->d_name); /*If two directories exist at the same level the path is built wrong and needs to be corrected*/ if((chdir(currentPath)) == -1){ chdir(".."); getcwd(currentPath, FILENAME_MAX); strcat(currentPath, "/"); strcat(currentPath, dit->d_name); for(i = 0; i d_name); depth++; helper(dip, dit, statbuf, currentPath, depth, argv); } else{ for(i =0; i d_name); chdir(currentPath); depth++; helper(dip, dit, statbuf, currentPath, depth, argv); } } 

    Вы используете S_ISREG() и S_ISDIR() правильно, вы просто используете их неправильно.

    В while((dit = readdir(dip)) != NULL) цикл в main , вы вызываете stat on currentPath снова и снова без изменения currentPath :

     if(stat(currentPath, &statbuf) == -1) { perror("stat"); return errno; } 

    dit->d_name вы не dit->d_name косую черту и dit->d_name в dit->d_name чтобы получить полный путь к файлу, который вы хотите установить? Понимает, что аналогичные изменения в ваших других вызовах stat также необходимы.

    [Отправлено от имени fossuser] Благодаря «mu слишком короткий» я смог исправить ошибку. Вот мой рабочий код был отредактирован для тех, кто ищет хороший пример (поскольку я не мог найти других в Интернете).

     #include  #include  #include  #include  #include  #include  #include  #include  void helper(DIR *, struct dirent *, struct stat, char *, int, char **); void dircheck(DIR *, struct dirent *, struct stat, char *, int, char **); int main(int argc, char *argv[]){ DIR *dip; struct dirent *dit; struct stat statbuf; char currentPath[FILENAME_MAX]; int depth = 0; /*Used to correctly space output*/ /*Open Current Directory*/ if((dip = opendir(".")) == NULL) return errno; /*Store Current Working Directory in currentPath*/ if((getcwd(currentPath, FILENAME_MAX)) == NULL) return errno; /*Read all items in directory*/ while((dit = readdir(dip)) != NULL){ /*Skips . and ..*/ if(strcmp(dit->d_name, ".") == 0 || strcmp(dit->d_name, "..") == 0) continue; /*Correctly forms the path for stat and then resets it for rest of algorithm*/ getcwd(currentPath, FILENAME_MAX); strcat(currentPath, "/"); strcat(currentPath, dit->d_name); if(stat(currentPath, &statbuf) == -1){ perror("stat"); return errno; } getcwd(currentPath, FILENAME_MAX); /*Checks if current item is of the type file (type 8) and no command line arguments*/ if(S_ISREG(statbuf.st_mode) && argv[1] == NULL) printf("%s (%d bytes)\n", dit->d_name, (int)statbuf.st_size); /*If a command line argument is given, checks for filename match*/ if(S_ISREG(statbuf.st_mode) && argv[1] != NULL) if(strcmp(dit->d_name, argv[1]) == 0) printf("%s (%d bytes)\n", dit->d_name, (int)statbuf.st_size); /*Checks if current item is of the type directory (type 4)*/ if(S_ISDIR(statbuf.st_mode)) dircheck(dip, dit, statbuf, currentPath, depth, argv); } closedir(dip); return 0; } /*Recursively called helper function*/ void helper(DIR *dip, struct dirent *dit, struct stat statbuf, char currentPath[FILENAME_MAX], int depth, char *argv[]){ int i = 0; if((dip = opendir(currentPath)) == NULL) printf("Error: Failed to open Directory ==> %s\n", currentPath); while((dit = readdir(dip)) != NULL){ if(strcmp(dit->d_name, ".") == 0 || strcmp(dit->d_name, "..") == 0) continue; strcat(currentPath, "/"); strcat(currentPath, dit->d_name); stat(currentPath, &statbuf); getcwd(currentPath, FILENAME_MAX); if(S_ISREG(statbuf.st_mode) && argv[1] == NULL){ for(i = 0; i < depth; i++) printf(" "); printf("%s (%d bytes)\n", dit->d_name, (int)statbuf.st_size); } if(S_ISREG(statbuf.st_mode) && argv[1] != NULL){ if(strcmp(dit->d_name, argv[1]) == 0){ for(i = 0; i < depth; i++) printf(" "); printf("%s (%d bytes)\n", dit->d_name, (int)statbuf.st_size); } } if(S_ISDIR(statbuf.st_mode)) dircheck(dip, dit, statbuf, currentPath, depth, argv); } /*Changing back here is necessary because of how stat is done*/ chdir(".."); closedir(dip); } void dircheck(DIR *dip, struct dirent *dit, struct stat statbuf, char currentPath[FILENAME_MAX], int depth, char *argv[]){ int i = 0; strcat(currentPath, "/"); strcat(currentPath, dit->d_name); /*If two directories exist at the same level the path is built wrong and needs to be corrected*/ if((chdir(currentPath)) == -1){ chdir(".."); getcwd(currentPath, FILENAME_MAX); strcat(currentPath, "/"); strcat(currentPath, dit->d_name); for(i = 0; i < depth; i++) printf (" "); printf("%s (subdirectory)\n", dit->d_name); depth++; helper(dip, dit, statbuf, currentPath, depth, argv); } else{ for(i =0; i < depth; i++) printf(" "); printf("%s (subdirectory)\n", dit->d_name); chdir(currentPath); depth++; helper(dip, dit, statbuf, currentPath, depth, argv); } } 
    Interesting Posts

    Dreamweaver не загружается из-за проблемы с файлом рабочего пространства

    Как заставить Outlook постоянно использовать данный язык для проверки?

    Является ли SecureString когда-либо практичным в приложении C #?

    VBScript – Использование обработки ошибок

    ArrayIndexOutOfBoundsException при использовании iteratorа ArrayList

    Как определить применение Lisp в Haskell?

    Могу ли я изменить и обновить настройки BIOS просто из графического интерфейса Windows (кольцо 3)?

    Windows 7 заблокирована в учетной записи администратора, которая не имеет пароля

    Выключите жесткий диск, если он не используется.

    Как изменить хром-пакетный идентификатор приложения Или Почему нам нужно ключевое поле в манифесте. Json?

    pip3 устанавливает внутри виртуальную среду с ошибкой python3.6 из-за недоступности модуля ssl

    Сетевой адаптер VirtualBox не удается установить

    Когда «жирная стрелка» (=>) привязывается к «этому» экземпляру

    Как перенести / скопировать файлы cookie из одного браузера в другой или один и тот же браузер с одной машины на другую?

    Сколько Include я могу использовать в ObjectSet в EntityFramework для сохранения производительности?

    Давайте будем гением компьютера.