收藏 分销(赏)

c语言下实现ls命令.docx

上传人:二*** 文档编号:4576763 上传时间:2024-09-30 格式:DOCX 页数:13 大小:30.71KB 下载积分:5 金币
下载 相关 举报
c语言下实现ls命令.docx_第1页
第1页 / 共13页
本文档共13页,全文阅读请下载到手机保存,查看更方便
资源描述
Linux下实现Is命令(仅适用于 Is -a pathname ; Is T pathname; Is pathname ) Is命令就是list的缩写,缺省下Is用来打印出当前目录的清单,如果I S指定其他目录,那么就会显示指定目录里的文件及文件夹清单。通过Is命令 不仅可以查看linux文件夹包含的文件.而且可以查看文件权限(包括目录、文 件夹、文件权限),查看目录信息等等,Is命令在日常的linux操作中用的很多 -a选项:表示显示该目录下的所有文件,包括隐藏文件。 -I选项:表示显示文件的详细信息,包括方问权限,文件大小…… 例如:Is -a /Is - I / 1)主要构造的函数void error (const char *err string, int line); 〃错误处理函数,打印错误所在行数和错误信息void Demonstrate attribute (struct stat buf, char *name); 〃获得文件属性并打印void Demonstrate si ng Ie (char *name); 〃输出文件名,命令没有-1选项。输出文件名要保持上下对齐void Demonstrate(int flag, char *pathname); 〃根据命令行参数和文件路径名来显示目标文件void Demonstrate dir (int 千lag parameter, char *path); 〃为显示某个目录下的文件做准备2)函数流程 (1)获取该目录下文件的总数和最长文件名(2)假设获该目录下所有文件的文件名,存放于变量f i lenames中 (3)使用冒泡法对文件名按字母顺序存储于fi lenanes中(4)调用Demonstrate。函数来显示每个文件信息 3)程序中主要的结构体: 参数struct stat *buf是一个保存文件状态信息的结构体A):struct stat { dev st dev;〃文件设备号ino t st ino;〃文件的 i-node mode t st mode;〃文件类型和存储权限nl ink t st nI ink;〃连到该文件的硬链接数目。 uid t st uid:〃文件所有者的用户idgid t st Mid;〃文件所有者的组id dev t st rdev:〃假设此文件为设备文件,那么为其设备编号off t st size;〃文件大小 blksize t st blksize;〃文件系统的I/O缓冲区大小blkcnt t st blocks;〃占用文件区块的个数 time t st atime;〃文件最近一次被访问的时间 文件最后一次被修改的时间 time_t st_ctime;〃文件最近一次被更改的时间 }其中,对于st nxxJe包含的文件类型信息,P0SIX标准定义了一系列的宏: S ISLNK (st mode) 〃判断是否为符号链接S_ISREG (st_mode) 〃判断是否为一般文件 /***用Istat而不是stat以方便解析链接文件 */if ( I stat (pathname, &buf) = -1 ) 〃I stat返回的是符号链接文件文件本身 的4犬态信息 (error ("stat", _LINE_J ; 1 ——switch (flag) (case PARAMETER NONE: 〃没有一I选项 if (name[0] !='.')( Demonstrate_s ingle (name);} " break;case PARAMETER A: // -a:显示包括隐藏文件在内的所有文件 Demonstrate single(name);break; case PARAMETER L: 〃-1:每个文件单独占一行,显示文件的详细属性信息if (name[0] !=') (Demonstrate attr ibute(buf, name); printfC' %-s\n", name);1 break;case PARAMETER A + PARAMETER L: 〃同时有-a 和选项的情况 Demonstrate attr ibute(buf, name);printfC' 5{ns\n", name); break;default: break;} 1/*为显示目录下的文件做准备*/ void Demonstrate_dir(int flag_parameter, char *path)( DIR*dir;struct d i rent *ptr; int count = 0;char fi Ienames[256] [PATH MAX + 1 ], tenp[PATH_MAX + 1]; 〃获取该目录下文件总数和最长的文件名dir = opendir (path); if (dir = NULL) error ("opendir", _LINE__);1 whi Ie ((ptr 二 readdir (dir)) != NULL) if (g maxlen < str Ien(ptr->d name))r maxlen = str Ien (ptr->d_name); count++;1 c I osed i r (d i r);if (count > 256) error ("too many f i les under this dir",_LINE_);int i, i, len = str I en (path); 〃获取该目录下所有的文件名dir = opendir (path); for (i = 0; i < count; i++) (ptr = readd i r (d i r); if( ptr = NULL) (error ("readdir",_LINE_); )strncpv (f i lenames [i], path, I en); //f i I enames 存放目录下的所有文件名 f i Ienames[i] [Ien] = *\0';str cat (f i I enames [ i ]. ptr->d name); f i Ienames[i] [len + str Ien (ptr->d_name)]二’\0’;) 〃使用冒泡法对文件名进行排序,排序后文件名按字母顺序存储于千i lenan^s for (i = 0; i < count-1; i++)for (j = 0; j < count - 1 - i; j++) (if ( strcnp(fi lenames[j], fi Ienames[j + 1]) > 0 ) (strcpv(tenp.fi Ienames[j + 1]); temp [str I en (f i I enames [ i + 1])]='\0';strcpv(f i Ienames[i + 1], f i Ienames[j]); fi Ienames[j + 1] [strlen(fi Ienames[j])] = '\0';strcpv(f i Ienames[ j], tew): f i Ienames[j] [str Ien(terrp)] = '\0";1 )for (i = 0: i < count; i++) Demonstrate (flagj^arameter, fiIenames[i]);「I I r (, 〃如果命令行$没有-|选项,打印一个换行符if( (flag parameter & PARAMETER_L) = 0) printf ("Xn'1);) 附录资料:不需要的可以自行删除Abstract: Based on the comprehensive analysis on the plastic part's structure service requirement, mounding quality and mould menu factoring cost. A corresponding injection mould of internal side core pulling was designed. By adopting the multi-direction and multi-combination core-pulling. A corresponding injection mould of internal side core pulling was designed, the working process of the mould was introduced C语言详解-枚举类型注:以下全部代码的执行环境为VC++ 6.0 在程序中,可能需要为某地整数定义一个别名,我们可以利用预处理指令#define来完成这 项工作,您的代码可能是: # dcfinc MON 1define TUE 2 # define WED 3define THU 4 # define FRI 5define SAT 6 # define SUN 7在此,我们定义一种新的数据类型,希望它能完成同样的工作。这种新的数据类型叫枚举型。 1 .定义一种新的数据类型一枚举型 以下代码定义了这种新的数据类型一枚举型enum DAY { MON=LTUE, WED, THU, FRI, SAT, SUN}; (I)枚举型是一个集合,集合中的元素(枚举成员)是一些命名的整型常量,元素之间用逗号, 隔开。 ⑵DAY是一个标识符,可以看成这个集合的名字,是一个可选项,即是可有可无的项。 (3)第一个枚举成员的默认值为整型的0,后续枚举成员的值在前一个成员上加1。 (4)可以人为设定枚举成员的值,从而自定义某个范围内的整数。 (5)枚举型是预处理指令#define的替代“(6)类型定义以分号;结束。 2 .使用枚举类型对变量进行声明新的数据类型定义完成后,它就可以使用了。我们已经见过最基本的数据类型,如:整型int, 单精度浮点型float,双精度浮点型double,字符型char,短整型short等等。用这些基本数据 类型声明变量通常是这样: char a; 〃变量a的类型均为字符型char charletter;inix, y, z; 〃变量x,y和z的类型均为整型int int number;double m, n; double result; 〃变量result的类型为双精度浮点型double 既然枚举也是一种数据类型,那么它和基本数据类型一样也可以对变量进行声明。 方法■:枚举类型的定义和变量的声明分开enum DAY ( MON= 1, TUE, WED. THU, FRI, SAT, SUN }; enum DAY yesterday;enum DAY today; enum DAY tomorrow; 〃变量(omorrow 的类型为枚举型 enum DAYenum DAY good_day, bad_day; 〃变量 good_day 和 bad_day 的类型均为枚举型 enum DAY 方法二:类型定义与变量声明同时进行: enum〃跟第一个定义不同的是,此处的标号DAY省略,这是允许的。 {Saturday, sunday = 0, monday, luesday, Wednesday, thursday, friday } workday; 〃变量workday的类型为枚举型enum DAYenum week { Mon=l, Tue, Wed. Thu. Fri Sal, Sun} days; 〃变量 days 的类型为枚举型 enum week enum BOOLEAN { false, true } end_flag, malch_flag; 〃定义枚举类型并声明了两个枚举型变 量方法三:用typedef关键字将枚举类型定义成别名,并利用该别名进行变量声明: typcdef enuni workday { Saturday, sunday = 0, monday, tuesday, Wednesday, thursday, friday} workday; 〃此处的workday为枚举型enum workday的别名 workday today, tomorrow; 〃变量 today 和 tomorrow 的类型为枚举型 workday,也即 enum workdayenurn workday 中的 workday 可以省略: typcdcf cnum {Saturday, sunday = 0, monday, tuesday, Wednesday, thursday, Friday } workday; //此处的workday为枚举型cnum workday的别名workday today, tomorrow; 〃变量 today 和 tomorrow 的类型为枚举型 workday,也即 enum workday 也可以用这种方式: typedef enum workday |Saturday, sunday = 0, inonday, tuesday, Wednesday, thursday, friday 1;workday today, tomorrow; 〃变量 today 和 tomorrow 的类型为枚举型 workday,也即 enum workday 注意:同一个程序中不能定义同名的枚举类型,不同的枚举类型中也不能存在同名的命名常 量。错误例如如下所示: 错误声明一:存在同名的枚举类型typedef enum { Wednesday, thursday, friday } workday;typedef enum WEEK ( Saturday, sunday = 0, nionday, } workday;错误声明二:存在同名的枚举成员 typedef enum { Wednesday, thursday, friday } workday」;typedef enum WEEK { Wednesday, sunday = 0, monday, } workday_2;.使用枚举类型的变量 2.1 对枚举型的变量赋值。 实例将枚举类型的赋值与基本数据类型的赋值进行了比照: 方法一:先声明变量,再对变量赋值#include<stdio.h> /*定义枚举类型*/enum DAY { MON=1,TUE, WED, THU, FRI, SAT, SUN }; void main()( /*使用基本数据类型声明变显,然后对变显赋值*/ int x, y, z; x= 10; y = 20; z = 30; /*使用枚举类型声明变量,再对枚举型变量赋值*/ enum DAY yesterday, today, tomorrow; yesterday = MON; today = TUE; tomorrow = WED; printf("%d %d %d \n", yesterday, today, tomorrow);} 方法二:声明变量的同时赋初值#include <stdio.h> /*定义枚举类型*/enum DAY { MON=1,TUE, WED, THU, FRI, SAT, SUN }; void main(){ /*使用基本数据类型声明变量同时对变量赋初值*/ int x=10, y=20, z=30; /*使用枚举类型声明变量同时对枚举型变量赋初值*/ enum DAY yesterday = MON, today = TUE, tomorrow = WED; printf("%d %d %d \n'\ yesterday, today, tomorrow);方法三:定义类型的同时声明变量,然后对变量赋值。 #include <stdio.h>/*定义枚举类型,同时声明该类型的三个变量,它们都为全局变量*/ enum DAY { MON=1, TUE, WED, THU, FRI, SAT, SUN } yesterday, today, tomorrow;/*定义三个具有基本数据类型的变量,它们都为全局变量*/ int x, y, z;void main() { /*对基本数据类型的变量赋值*/ x = 10; y = 20: z = 30; /*对枚举型的变量赋值*/ yesterday = MON; today = TUE; tomorrow = WED; printf("%d %d %d \n", x, y, z); 〃输出:10 20 30 printf("%d %d %d \n'\ yesterday, today, tomorrow); 〃输出:I 2 3) 方法四:类型定义,变量声明,赋初值同时进行。 #includc <stdio.h>/*定义枚举类型,同时声明该类型的三个变量,并赋初值。它们都为全局变量*/ enum DAY{ MON=I, TUE, WED, THU, FR1, SAT, SUN) yesterday = MON, today = TUE, tomorrow = WED;/*定义三个具有基本数据类型的变量,并赋初值。它们都为全局变量*/ int x = 10, y = 20, z = 30;void main() printf("%d %d %d \n", x, y, z); 〃输出:10 20 30 printf("%d %d %d \n", yesterday, today, tomorrow); 〃输出:12 3) 2.2 对枚举型的变量赋整数值时,需要进行类型转换。 #include <stdio.h>enum DAY { MON=1,TUE, WED, THU. FRI, SAT. SUN ); void main(){ enum DAY yesterday, today, tomorrow; yesterday = TUE; today = (enum DAY) (yesterday + 1); 〃类型转换 tomorrow = (enum DAY) 30; 〃类型转换 //tomorrow = 3; 〃错误 printf("%d %d %d \n'\ yesterday, today, tomorrow); 〃输出:2 3 30 I使用枚举型变量 #include<stdio.h>enum { BELL= W, BACKSPACE = '\b', HTAB='\t', RETURN= '\r; NEWLINE = '\n', VTAB=W, SPACE=" enum BOOLEAN { FALSE = 0, TRUE } match_flag;void main() { int index = 0; int count_ofllcttcr = 0; int count_oOpace = 0; char str[] = "I'm Ely efod"; match_flag = FALSE; for(; str[index] != ''0'; index++)if( SPACE != str[index]) count_oflletter++; else( match_flag = (enuni BOOLEAN) 1;count_oflspace++; )printf("%s %d times %c", match_flag ? "match": "not match", count_oflspace, NEWLINE); printf("count of letters: %d %c%c", count_oLletter, NEWLINE, RETURN); 1输出: match 2 timescount of letters: 10 Press any key to continue4.枚举类型与sizeof运算符 #include <stdio.h>enum escapes { BELL= BACKSPACE = \b', HTAB= *\t', RETURN ='\r; NEWLINE = '\n', VTAB= '\v\ SPACE="}; enum BOOLEAN { FALSE = 0, TRUE } match_flag;void main() { printf("%d bytes \n", sizeof(enum escapes)); //4 bytes printf("%d bytes \n", sizcof(cscapcs)); //4 bytes printf("%d bytes \n", sizeof(enum BOOLEAN)); //4 bytes printf("%d bytes \n", sizeof(BOOLEAN)); //4 bytes printf("%d bytes \n", sizeof(match_flag)); //4 bytesS ISDIR (st mode) 〃判断是否为目录文件 S I SOP (st mode) 〃判断是否为字符设备文件S IBLK (st mode) 〃判断是否为块设备文件 S ISFIFO (st mode) 〃判断是否为先进先出FIFOS ISFOCK (st mode) //判断是否为 socket B): struct passwd *psd; 〃从该结构体中获取文件所有者的用户名C): struct group *grp; 〃从该结构体中获取文件所有者所属组的组名 4)心得体会本次课程设计我写的是Linux下的Is命令,通过这次课程设计,不仅使我对Is 命令有了更深一层的认识,还认识到了系统提供的命令实现的途径和方法。之前 总是使用系统命令,如今自己编程实现了一些命令,每次使用系统提供的命令和 调用自己编写的命令感觉大不相同。 5)具体解析与详细代码: #include <stdio. h>#include <stdlib. h> #include <str ing. h>#include <time. h> #include <sys/stat. h>#include <unistd. h> #include <sys/types. h>include <1 inux/l imits. h> # include <dirent. h>include <grp. h> # include <pwd. h>include <errno. h> # define PARAMETER NONE 0 〃无参数define PARAMETER A 1 // -a:显示所有文件 # define PARAMETER L 2// T : 一行显示一个文件的详细信息define MAXROWLEN 80 〃一行显示的最多字符数 int r leave len二MAXROWLEN; 〃一行剩余长度,用于输出对齐int g max I en; 〃存放某目录下最长文件名的长度 void error (const char *err_string, int line); 〃专酊吴处理函数,打印4 酊吴 所在行数人错误信息void Demonstrate attr ibute(struct stat buf, char * name); 〃获取文件属 性并打印 void Demonstrate single (char * name);〃输出文件名,命令没有T 选项,那么 输出文件名时要保持上下文对齐void Demonstrate(int flag, char * pathname); /"艮^^令行豺攵牙口文彳牛*'各 径名显示目标文件 void Demonstrate_dir (int f lag_parameter, char * path); 〃为显示某个目 录下的文件做准备一int main(int argc, char ** argv) int i, j, k, nun; printf("%d bytes \n", sizeof(SPACE)); //4 bytes printf("%d bytes \n", sizeof(NEWLINE)); //4 bytes printf("%d bytes \n", sizeof(FALSE)); //4 bytes printf("%d bytes \n", sizeof(0)); //4 bytes) 5.综合举例#include<stdio.h> enum Season{ spring, sunimer= 100, fall=96, winter1; typedef enum{ Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, SundayI Weekday;void main() { /* Season */ printf("%d \n", spring);//0 printf("%d, %c \n", summer, summer); // 100, d printf("%d \n\ fall+winter);// 193 Season mySeason=winter; if(winter==mySeason)printf("myScason is winter \n"); // myScason is winter int x= 10(); if(x==summer)printf("x is equal to summer\n"); 〃 x is equal to summer printf("%d bytes\n", sizeof(spring)); // 4 bytes /* Weekday */ printf("sizcof Weekday is: %d \n", sizcof(Wcckday)); //sizcof Weekday is: 4 Weekday today = Saturday; Weekday tomorrow; if(today == Monday)tomorrow = Tuesday; elsetomorrow = (Weekday) (today + 1); //remember to convert from int to Weekday 本文来自CSDN--xiaobai32966博客 char path [PATH MAX+1]; 〃文件路径名 char parameter [32];〃保存命令行参数,目标文件名和目录名不在此列 int flag paraneter二PARAMETER_NONE; 〃用来标志参数种类,即是否有T和- a选项 struct stat buf; /*首先对命令行参数进行解析,即提取命令行参数中后的选项。用户的输入有 多样性,如Is-1 -a; Is-la。我们用两层循环类来解析参数.外层循环对a rgv □数组中的元素依次进行内层循环的解析,二层循环对以=为首的字符 串进行选项提取.并把每个选项存于parameter □数组当中,用nun记下'-' 的数目,以备后用。而命令行参数中的总选项数目那么用j计数。 */ i = 0, num = 0; for (i = 1 ; i < argc; i++) ( if (argv[i] [0]='-1) ( for (k = 1; k < str len(argv[i]); k++) ( parameter [j] = argv[i] [k]; 〃获取一后面的参数保存到数组parameter中 J44-; 1 nuE; //保存的个数 1 ) /*检查刚刚提取的选项是否合法。并且用或运算记录参数,以备后用。最后为选项数 组的末尾元素赋,\0'。 */ //check the argunent because of only supporting -a ang -I for(i = 0; i < j; i++) ( if (parameter[i] = 'a1) ( f lag_parameter = PARAMETERA; continue; ) , else if (parameter[i] = 'I') ( flag parameter = PARAMETER_L; continue; 1 elseprintf ("my_ls: invaI id option Tk)\n”, parameter[i]); exit (1); ) 1 parameter [j] = '\0';/* 由上面所知num记录的是参数中‘-’的数量,因此如果num+1=argc,那说明 用户所输入的命令行参数不包含目录或文件名。只是显示当前目录下的文件。因 为这是我们必须自动将path赋值为当前目录。为了使其称为一个字符串,必须 在末尾加'\0'。然后进入Demonstrate_dir函数. *///print the information of current directory if the cannand without th e name of target f i Ie and current directory if ((num + 1) = argc) {strcpy(path, /");// /"当前目录 path [2] = '\0': Demonstrate_d i r (f I ag_parameter, path); return 0;1 /* 如果命令行参数包含目录或者文件名,那么我们要检查其合法性(参数中 的目录或者文件是否存在)。这里我们利用stat族函数来获取文件的属性,实现 上述功能。stat族函数通常有两个参'数:文件路径/文件描述符.struct stat *buf类型的结构体。如果操作成功,那么buf将保存文件的属性。假设合法,利 用宏S ISDIR(buf. st mode),判断此文件是否为目录文件。假设为目录文件那么进入 Demonstrate dir 函数,否那么进入Demonstrate 函数。通常情况,Demonstrate dir函数是获取path目录下所有文件的完整路径玄,在使每个文件执行Demons trate函数。因此如果参数中是指定的文件名.那么可绕过 Demonstrate_d i r 函数,直接进入 Demonstrate 函数。 */ i=1; do { /* 梆如果不是目标文件名或目录,解析下一个命令行参数 */if (argv[i][0]='」) ( i『continue;1 else strcpy (path, argv[i]);/* 林如果目标文件或目录不存在,报错并退出程序*/ if ( stat (path, &buf) = -1 )( error ("stat", _LINE_J ;1 if ( S ISDIR(buf. st mode) ) // argv[i]是一个目录〃如果目录的最后一个字符不是就加上'/' (if (path] strlen(argv[i])-1 ] != '/') (path[ strlen(argv[i]) ] = '/': path[ str len(argv[i])+1 ]='\0';1 else( path[ str len(argv[i]) ] = >\0';) Demonstrate_d i r (f I ag_parameter, path);if 1else //argv[i]是一个文件 (Demonstrate (f I ag_parameter, path); i++;) )} whi Ie (i < argc); return 0;1 /*料错误处理函数,打印出错误所在行的行数和错误信息 */void error (const char *err_str ing, int I ine) (fprintf(stderr, “line:%d ", line); perror (err_str ing);exit(1); 1/* **获取文件属性并打印*/ void Demonstrate_attr ibute(struct stat buf, char * name) char buf time[32]: 〃存放时间struct passwd *psd; 〃从该结构体中获取文件所有者的用户名 struct group *grp; 〃从该结构体中获取文件所有者所属组的组名 /***获取并打印文件类型 *///st mode:文件内容禾^存取权限 if (S_ISLNK(buf. stjnode)) 〃判断是否为符号链接( printfC'l");) else if (S_lSREG(buf. st_mode)) 〃判断是否为文件( printf ;} else if (S_ISDIR(buf. st_mode)) 〃判断是否为目录{ pr intf ("d");) else if (S_ISCHR(buf. st_mode)) 〃判断是否为字符设备文件( printf ("c");} else if (S_ISBLK(buf. st_mode)) 〃判断是否为块设备文件( printf ("b");) else if (S_ISFIFO(buf. st_mode)) 〃判断是否为先进先出的FIFO (printfCT'); )else if (S_ISSOCK(buf. st_mode)) 〃判断是否为 socket (printf ("s"); )/* 林获取并打印文件所有者的权限*/ if (buf. st_mode & S_IRUSR)( printfC'r");) else( printf ;) if (buf. st_mode & S_IWUSR) (pr intf ("w"); ) else ( printf ;1 if (buf. st_mode & S_IXUSR) (printf ("x"); 1else ( printf ; 林获取并打印与文件所有者同组的用户对该文件的操作权限*/ if (buf. st_mode & S_IRGRP)( pr intf ("r");1 else( printf ;1 if (buf. st_mode & S_IWGRP)( printfC'w");1 else( printf ;1 if (buf. st_nDde & S_IXGRP)( printfC'x");) else( printf ;) /***获取并打印其它用户的对该文件的操作权限 */if (buf. st_mode & S_IROTH) ( printfC'r");1 else ( printf C-");) if (buf. st_mode & S_IWOTH) (pr intf ("w"); )else (printf ; )if (buf. st_mode & S_IXOTH) ( printfC'x");1 elsef printf ;1 printfC'");/*
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 通信科技 > 开发语言

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服