日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

UNIX-LINUX编程实践教程-第三章-实例代码注解-ls2

發布時間:2025/3/8 linux 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 UNIX-LINUX编程实践教程-第三章-实例代码注解-ls2 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一 問題

  對ls1的功能進行擴展,以達到類似ll命令的功能。

二 分析

  在ls1中,我們利用readdir()函數和dirent結構體來獲得目標文件夾內的文件名(dirent->d_name)。
  現在我們借助函數stat()和結構體stat以及上面得到的文件名來獲得該目錄內文件的詳細信息(參看后面的“相關函數與結構體”部分)。

三 實現

1 頭文件

#include<stdio.h> #include<sys/types.h> #include<dirent.h> #include<sys/stat.h> #include<string.h>

2 相關函數聲明

void do_ls(char dirname[]); void dostat(char *filename); void show_file_info(char *filename,struct stat *info_p); void mode_to_letters(int mode,char str[]); char *uid_to_name(uid_t uid); char *gid_to_name(gid_t gid);

3 主函數

獲得目錄的路徑,并將該路徑傳遞給do_ls()函數

main(int ac,char *av[]) {if(ac == 1){do_ls(".");}else{while(--ac){printf("%s:\n",*++av);/* 傳遞目錄路徑到do_ls函數 */do_ls(*av);}} }

4 do_ls()函數

結合opendir()函數和readdir()函數,通過目錄的路徑獲得該目錄內各文件或文件夾的名稱,并將該名稱傳遞給dostat()函數

void do_ls(char dirname[]) {DIR *dir_ptr;struct dirent *direntp;/* 使用opendir()函數“打開”目錄,返回指向該目錄的指針 */if((dir_ptr = opendir(dirname))==NULL){fprintf(stderr,"ls2:cannot open %s\n",dirname);}else{/* 使用readdir()函數讀取指針指向的目錄,獲得dirent結構體 */while((direntp = readdir(dir_ptr))!=NULL){/* 通過dirent結構體獲得文件名,并將文件名傳遞給dostat()函數 */dostat(direntp->d_name);}closedir(dir_ptr);} }

5 dostat()函數

使用stat()函數,通過文件或文件夾的名稱獲得保存了該文件信息的stat結構體,將該結構體傳遞給show_file_info()函數

void dostat(char *filename) {struct stat info;/* 使用stat()函數,通過文件名獲得stat結構體info */if(stat(filename,&info) == -1){perror(filename);}else{/* 將stat結構體傳遞給show_file_info()函數 */show_file_info(filename,&info);} }

6 show_file_info()函數

將stat結構體中的各項參數分別解析并輸出到標準輸出

void show_file_info(char *filename,struct stat *info_p) {/* 各解析函數聲明 */char *uid_to_name(),*ctime(),*gid_to_name(),*filemode();void mode_to_letters();char modestr[11];/* 解析并輸出文件的mode信息 */mode_to_letters(info_p->st_mode,modestr);printf("%s",modestr);/* 文件連接數 */printf("%4d",(int)info_p->st_nlink);/* 通過uid獲得對應的用戶名 */printf("%-8s",uid_to_name(info_p->st_uid));/* 通過gid獲得對應的組名 */printf("%-8s",gid_to_name(info_p->st_gid));/* 文件大小 */printf("%8ld",(long)info_p->st_size);/* 最近一次修改時間 */printf("%.12s",4+ctime(&info_p->st_mtime));/* 文件名 */printf("%s\n",filename); }

?7?mode_to_letters()函數

將傳遞進來的mode參數解析成string格式

void mode_to_letters(int mode,char str[]) {strcpy(str,"----------");if(S_ISDIR(mode)) str[0] = 'd';if(S_ISCHR(mode)) str[0] = 'c';if(S_ISBLK(mode)) str[0] = 'b';if(mode&S_IRUSR) str[1] = 'r';if(mode&S_IWUSR) str[2] = 'w';if(mode&S_IXUSR) str[3] = 'x';if(mode&S_IRGRP) str[4] = 'r';if(mode&S_IWGRP) str[5] = 'w';if(mode&S_IXGRP) str[6] = 'x';if(mode&S_IROTH) str[7] = 'r';if(mode&S_IWOTH) str[8] = 'w';if(mode&S_IXOTH) str[9] = 'x'; }

其中S_ISDIR、S_ISCHR、S_ISBLK等是宏,定義如下所示:

#define S_ISFIFO(m) (((m)(0170000)) == (0010000)) #define S_ISDIR(m) (((m)(0170000)) == (0040000)) #define S_ISCHR(m) (((m)(0170000)) == (0020000)) #define S_ISBLK(m) (((m)(0170000)) == (0060000)) #define S_ISREG(m) (((m)(0170000)) == (0100000))

8?uid_to_name()函數

通過用戶的uid,利用getpwuid()函數,將uid轉換為用戶名

#include<pwd.h> char *uid_to_name(uid_t uid) {struct passwd *getpwuid(),*pw_ptr;static char numstr[10];if((pw_ptr = getpwuid(uid))==NULL){sprintf(numstr,"%d",uid);return number;}else{return pw_ptr->pw_name;} }

9?gid_to_name()函數

通過用戶的gid,利用getgrgid()函數,將gid轉換為組名

#include<grp.h> char *gid_to_name(gid_t gid) {struct group *getgrgid(),*grp_ptr;static char numstr[10];if((grp_ptr = getgrgid(gid))==NULL){sprintf(numstr,"%d",gid);return numstr;}else{return grp_ptr->gr_name;} }

?

相關函數與結構體

1 stat()函數
通過文件名獲取文件信息,并保存在stat結構體中
頭文件:#include <sys/stat.h>  #include <unistd.h>
函數原型 int stat(const char *file_name, struct stat *buf)
參數    file_name 指向文件名的指針
      buf 指向stat結構體的指針
返回值   0 執行成功
      -1 執行失敗,錯誤代碼存于ermo中

2 stat結構體
頭文件:#include<sys/stat.h>
struct stat
{
  mode_t st_mode; //文件對應的模式,文件,目錄等
  ino_t st_ino; //i-node節點號
  dev_t st_dev; //設備號碼
  dev_t st_rdev; //特殊設備號碼
  nlink_t st_nlink; //文件的連接數
  uid_t st_uid; //文件所有者
  gid_t st_gid; //文件所有者對應的組
  off_t st_size; //普通文件,對應的文件字節數
  time_t st_atime; //文件最后被訪問的時間
  time_t st_mtime; //文件內容最后被修改的時間
  time_t st_ctime; //文件狀態(屬性)改變時間
  blksize_t st_blksize; //文件內容對應的塊大小
  blkcnt_t st_blocks; //文件內容對應的塊數量
}

3 ctime()函數
把日期和時間轉換為字符串
頭文件:#include <cstdio>  #include <ctime>
函數原型?char *ctime(const time_t *time)
參數    time time_t格式的時間
返回值   char * 字符串格式的時間

4?getpwuid()函數
通過用戶的uid查找用戶的相關信息,并以passwd結構體返回其數據
頭文件:#include <sys/types.h>  #include <pwd.h>
函數原型?struct passwd *getpwuid(uid_t uid)
參數    uid 用戶的uid
返回值   passwd結構體 uid對應的用戶信息
      空指針 出錯

5?passwd結構體
struct passwd
{
  char * pw_name; /* Username, POSIX.1 */
  char * pw_passwd; /* Password */
  __uid_t pw_uid; /* User ID, POSIX.1 */
  __gid_t pw_gid; /* Group ID, POSIX.1 */
  char * pw_gecos; /* Real Name or Comment field */
  char * pw_dir; /* Home directory, POSIX.1 */
  char * pw_shell; /* Shell Program, POSIX.1 */
  char *pw_class;
  time_t pw_change;
  time_t pw_expire;
}

6?getgrgid()函數
通過gid,找到該組的相關信息,并以group結構體返回其信息
頭文件:#include<grp.h>  #include<sys/types.h>
函數原型?strcut group * getgrgid(gid_t gid)
參數    gid
返回值   group結構體 正常
      NULL 無數據或發生錯誤

7 group結構體
struct group
{
  char *gr_name; /*組名稱*/
  char *gr_passwd; /* 組密碼*/
  gid_t gr_gid; /*組識別碼*/
  char **gr_mem; /*組成員賬號*/
}

?

轉載于:https://www.cnblogs.com/cation/archive/2013/01/29/2875311.html

總結

以上是生活随笔為你收集整理的UNIX-LINUX编程实践教程-第三章-实例代码注解-ls2的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。