Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用S_ISREG()和S_ISDIR() POSIX宏?

如何使用S_ISREG()和S_ISDIR() POSIX宏?
EN

Stack Overflow用户
提问于 2011-02-14 06:28:43
回答 2查看 105.9K关注 0票数 13

这是我写的一个C程序,用于递归导航和输出目录和常规文件。它在我的Linux机器上编译和运行得很好。但是在Solaris上,因为没有d_type字段,所以dit->d_type == 8检查和其他类似的检查不起作用。我读过的一个解决这个问题的方法是使用S_ISREG()S_ISDIR()宏,但它们的工作方式与我目前在代码中使用它们的方式不同。我注释掉了在我的Linux机器上工作的代码行。

代码语言:javascript
运行
AI代码解释
复制
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <dirent.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

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 < depth; i++)
        printf("    ");
      printf("%s (%d bytes)\n", dit->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 < depth; i++)
      printf("    ");
    printf("%s (%d bytes)\n", dit->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 < 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);
  }

}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-02-14 06:50:05

您正确地使用了S_ISREG()S_ISDIR(),只是将它们用在了错误的地方。

mainwhile((dit = readdir(dip)) != NULL)循环中,您一次又一次地在currentPath上调用stat,而没有更改currentPath

代码语言:javascript
运行
AI代码解释
复制
if(stat(currentPath, &statbuf) == -1) {
    perror("stat");
    return errno;
}

你不应该在currentPath后面加上一个斜杠和dit->d_name来获得你想要stat的文件的完整路径吗?我认为还需要对其他stat调用进行类似的更改。

票数 17
EN

Stack Overflow用户

发布于 2012-03-28 00:10:07

我代表fossuser发帖,感谢"mu is too short“,我能够修复这个bug。这是我的工作代码,为那些寻找一个很好的例子的人而编辑(因为我在网上找不到其他的)。

代码语言:javascript
运行
AI代码解释
复制
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <dirent.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

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);
  }
}
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4989431

复制
相关文章
微软Windows 10的上下文菜单引入Fluent Design风格
微软正在将Fluent Design扩展到Windows 10的更多部分,本周早些时候发布的最新预览版本也带来了这方面的更多变化。在周五发布的更新版本说明中,微软透露Fluent Design在Windows 10 build 17692中也开始部署,半透明效果现在可用于XAML控件。 Windows 10的系统UI控件杂乱的问题一直是被用户诟病的对象,同一个鼠标右键可以按出五六种菜单的尴尬可能已经开始缓解。 Fluent Design现在可用于上下文菜单、弹出窗口、自动建议对话框和下拉菜单以及时间选择器弹
程序你好
2018/07/20
4370
adobe air是干什么的?
Adobe air 是知名软件公司Adobe旗下的产品之一。 Adobe[1]Integrated Runtime允许你利用现有的web开发技能(包括Flash, Flex, HTML, JavaScript, Ajax)优势,建立和配置跨平台(或跨操作系统)的桌面RIA(InternetApplications)应用。2.7以后的版本不再支持桌面Linux操作系统[2]。 对于用户来说,Adobe AIR 实现的跨平台应用,使其不再受限于不同的操作系统,在桌面上即可体验丰富的互联网应用。并且是比以往更低的资源占用、更快的运行速度和顺畅的动画表现。工具。例如 新浪微博客户端微博 AIR、Google Analytics 分析工具、Twitter 客户端 TweetDeck及众多最新影片介绍工具等。 AIR能使你在熟悉的环境下工作,去利用你觉得的最舒适的工具,并且通过支持Flash, Flex, HTML,JavaScript, 以及 Ajax,去建立接近你需要的尽可能好的体验。 AIR 是 Adobe Integrated Runtime的缩写,它是一个跨操作系统的运行时(Runtime),利用现有的Web开发技术(Flash,Flex,HTML,JavaScript,Ajax)来构建‘富Internet’(我一直觉得这个翻译很可悲,Rich被翻译成富后即拗口又不达意)应用程序并部署为桌面应用程序。 AIR 支持现有的Web技术如Flash,Flex,HTML,JavaScript和AJAX,可以用你最熟练的技术来开发您所见过的最具用户体验的RIA程序。 首先,Adobe air 是Adobe公司旗下的产品之一,如果用户用不到该软件,可以卸载。 其次,Adobe Integrated Runtime允许用户利用现有的web开发技能(包括Flash, Flex, HTML, JavaScript, Ajax)优势,建立和配置跨平台(或跨操作系统)的桌面RIA(InternetApplications)应用。对于用户来说,Adobe AIR实现的跨平台应用,使其不再受限于不同的操作系统,在桌面上即可体验丰富的互联网应用。并且是比以往更低的资源占用、更快的运行速度和顺畅的动画表现工具。例如新浪微博客户端、微博 AIR、Google Analytics 分析工具、Twitter 客户端 TweetDeck及众多最新影片介绍工具等。 通俗来说: Adobe Air就是利用Adobe公司的Flash技术开发的视频播放平台。这个视频播放终端运行平台的主要功能就是可以在网上看视频,跟Flash相同,但是功能更强大。 其实通俗的讲Adobe Air就是一个平台,这个平台提供一些软件接口,想开发软件的人员用这些接口和其他的编程技术可以开发出来一些软件。
iOS程序应用
2023/04/17
1.5K0
adobe air是干什么的?
windows经典菜单
StartIsBack+只支持Win8.1系统,Win8系统请使用StartIsBack。
Windows技术交流
2022/07/27
6500
Android 彩色上下文菜单 Context
本文原创首发CSDN,链接 https://blog.csdn.net/qq_41464123/article/details/106954710 ,作者博客https://blog.csdn.net/qq_41464123 ,转载请带上本链接,尤其是脚本之家、码神岛等平台,谢谢配合。
Designer 小郑
2023/08/01
2130
Android 彩色上下文菜单 Context
设置Sublime Text为Adobe Air的开发编辑器
在上一篇关于Adobe Air的文章中1,介绍了如何设置Air的开发环境,由于是跟Web差不多的开发方式,基本上Web所使用的编辑器都是适用的,像Dreamweaver、aptana studio等,当然还有Sublime Text。
GhostZhang
2022/08/22
4470
send,recv,sendto,recvfrom
int send( SOCKET s, const char FAR *buf, int len, int flags );
全栈程序员站长
2022/07/14
1.6K0
适用于windows && macos(intel/m1 Pro Max) Adobe 2022全家桶集合
相遇的日子总是那么难忘,当它以全新的姿态出现时,都会让人眼前一亮!特别是强大的功能和可编辑性,而且Adobe2022专门为m1 Pro Max芯片进行优化和适配,使得其不再需要转译器转译时,大大增加了硬件资源的利用率!从而加快了创作速度。今天,小编将为有需要的网友收集屏蔽验证,支持长期使用的Adobe2022全家桶软件。同时下载地址选用支持全速下载的阿里云盘。
Khan安全团队
2022/04/02
5.3K0
windows 右键菜单的添加和移除
windows下所有系统及部分软件的配置都在注册表中,注册表相当于是一个windows系统的数据库.我们想要增加或更改一些功能可以通过修改注册表的方法实现.
caoayu
2020/09/23
2.4K0
windows 右键菜单的添加和移除
【说站】python PyQt创建上下文菜单
2、将contextMenuPolicy设置为Qt.ActionsContextMenu,以便在上下文菜单中显示操作小部件。
很酷的站长
2022/11/24
3990
安卓开发_浅谈ContextMenu(上下文菜单)
长下文菜单,即长按view显示一个菜单栏 与OptionMenu的区别 OptionMenu对应的是activity,一个activity只能拥有一个选项菜单 ContextMenu对应的是View,每个View都可以设置上下文菜单 一般情况下ContextMenu常用语ListView或者GridView; 创建和响应上下文菜单过程: 1.在activity的onCreate(...)方法中为一个view注册上下文菜单 2.在onCreateContextMenuInfo(...)中生成上下文菜单。 3.
听着music睡
2018/05/18
1.5K0
sendto & recvfrom 详解
sendto和recvfrom一般用于UDP协议中,但是如果在TCP中connect函数调用后也可以用.
全栈程序员站长
2022/09/15
2.5K0
send()、sendto()和recv()、recvfrom()的使用
udp通讯中的sendto()需要在参数里指定接收方的地址/端口,recvfrom()则在参数中存放接收发送方的地址/端口,与之对应的send()和recv()则不需要如此,但是在调用send()之前,需要为套接字指定接收方的地址/端口(这样该函数才知道要把数据发往哪里),在调用recv()之前,可以为套接字指定发送方的地址/端口,这样该函数就只接收指定的发送方的数据,当然若不指定也可,该函数就可以接收任意的地址的数据。(这些内容前面文章udp通讯中的connect()和bind()函数 有详细讲过)
全栈程序员站长
2022/09/15
1.8K0
send()、sendto()和recv()、recvfrom()的使用
用于 Windows 下的日志跟踪分析工具(Tail for Windows)
在 Linux 下做开发和调试任务的时候,有些情况会动态去跟踪一些日志的变化来调试问题。Linux 下使用 tail -f 就可以达到需求了,但 Windows 下一直没有找到类似的好用工具,在 github 上也有一些开源项目,不是项目相对陈旧界面丑陋,就是功能不完善不能让人专注于分析日志。索性自己做了一个,预览图如下:
我与梦想有个约会
2020/01/05
1.3K0
用于 Windows 下的日志跟踪分析工具(Tail for Windows)
在 Linux 下做开发和调试任务的时候,有些情况会动态去跟踪一些日志的变化来调试问题。Linux 下使用 tail -f 就可以达到需求了,但 Windows 下一直没有找到类似的好用工具,在 github 上也有一些开源项目,不是项目相对陈旧界面丑陋,就是功能不完善不能让人专注于分析日志。索性自己做了一个,预览图如下:
我与梦想有个约会
2018/11/07
7.4K2
在Excel中自定义上下文菜单(下)
在本文开头的VBA示例中,你看到了如何通过使用工作簿的Activate和Deactivate事件调用宏来创建和删除菜单控件,从而来更改单元格上下文菜单。
fanjy
2022/11/16
2.7K0
用于 Windows 下的日志跟踪分析工具(Tail for Windows)
在 Linux 下做开发和调试任务的时候,有些情况会动态去跟踪一些日志的变化来调试问题。Linux 下使用 tail -f 就可以达到需求了,但 Windows 下一直没有找到类似的好用工具,在 github 上也有一些开源项目,不是项目相对陈旧界面丑陋,就是功能不完善不能让人专注于分析日志。索性自己做了一个,预览图如下:
我与梦想有个约会
2018/11/07
1.8K0
Windows开始菜单无响应
之前遇到过Windows开始菜单点击无响应,最近又遇到开始菜单搜索无响应或多次重启才可以使用。 所以我将解决方法记录一下方便自己。
繁华是客
2023/03/03
2.1K0
工作中遇到的小技巧 一(暂停更新)
       如果浏览器的缓存已满,服务速度可能会减慢,您可能无法下载和查看附件。一下是在Internet Explorer中清空浏览器缓存的步骤:
DannyHoo
2022/05/09
7930
工作中遇到的小技巧 一(暂停更新)
【说站】python PyQt事件处理实现上下文菜单
在创建上下文菜单的方法上,我们已经介绍过一种简单的方法。本篇所要带来的方法略有难度,但在控制和调用上比较方便。
很酷的站长
2022/11/24
3840
在Excel中自定义上下文菜单(上)
上下文菜单(也称为快捷菜单)是在一些随用户交互之后出现的菜单,通常是鼠标右键单击操作。在Microsoft Office中,上下文菜单提供了一组在应用程序的当前状态或上下文中可用的有限选项。通常,可用的选择是与选定对象(如单元格或列)相关的操作。
fanjy
2022/11/16
2.9K0
在Excel中自定义上下文菜单(上)

相似问题

Adobe Air -通过上下文菜单粘贴图像

12

Adobe Air for Windows 64位?

42

控制windows Adobe AIR的顺序

10

如果Adobe Air影响Adobe Air或与Adobe Air冲突

22

Adobe air -右键单击树节点时添加上下文菜单

12
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档