C语言实现实现Linux系统中ls

编程入门 行业动态 更新时间:2024-10-09 07:20:51

C<a href=https://www.elefans.com/category/jswz/34/1770116.html style=语言实现实现Linux系统中ls"/>

C语言实现实现Linux系统中ls

C语言实现实现Linux系统中ls -altr系统命令功能

一、学习内容

1、文件权限(如:d-rw-_r–_r–)

在Linux中使用八进制数表示的语法如下:r(4),w(2),x(1),-(0),前三位(rw-)表示文件拥有者的权限,本例中为4+2+0=6。中间三位(r–)表示是同组成员对这个文件所拥有的的权利,在本例中为4+0+0=4。最后三位(r–)表示的是其他群组的权限,在本例中为4+0+0=4,所以八进制数表示为644。
其中第一位代表的是文件类型,这里d表示文件属性为目录。具体如下:

  1. d:目录
  2. —:文件
  3. l:连接档
  4. b:装置文件里的可供存储的接口设备
  5. c:装置文件里的串行端口设备,例如键盘、鼠标

2、Linux中指令:ls、ls -l、ls -al区别

  • ls:显示不隐藏的文件与文件夹(仅当前文件名或目录名)
  • ls -l:显示不隐藏的文件与文件详细信息
  • ls -al:显示所有文件与文件夹的详细信息
  • ls -a:显示所有文件与文件夹的名字或目录名

3、链表创建以及链表节点的增加和删除

①单链表的创建过程有以下几步
1)定义链表的数据结构;
2)创建一个空表;
3)利用malloc()函数向系统申请分配一个节点;
4)讲新节点的指针成员赋值为空。若是空表,将新节点连接到表头;若是非空表,将新节点接到表尾;
5)判断一下是否有后续节点要接入链表,若有转到3),没有则结束;

②单链表的输出有如下几步
1)找到表头;
2)若是非空表,输出节点的值成员,是空表则退出;
3)跟踪链表的增长,即找到下一个节点的地址;
4)转到2);

③实现链表的创建
1)定义一个结构体类型来存储这个节点
链表中的每一个节点的数据类型为结构体类型,节点有两个成员:整型成员(实际要保存的数据)和指向下一个结构体类型节点的指针,即下一个节点的地址。

ex:struct node
{
int data;储存具体数值
struct node *next;存储下一个节点的地址,类型相同
};

2)链表的创建
1> 单链表有一个头结点head,指向链表在内存的首地址。当链表还没有建立时头指针为空(NULL)。
ex:struct node *head;

2> head = NULL;//头指针为空
创建第一个节点,并且临时指针p指向这个节点(利用malloc)。
ex:struct node *head;
p = (struct node *)malloc(sizeof(struct node));

3> 接下来分别设置新创建的这个节点的左半部分和右半部分
scanf(“%d”,&a);
p->data = a;//将数据存储到当前节点中
p->next = NULL;设置当前节点的下一个节点为空

二、代码实现

功能描述:使用C语言实现Linux系统中的ls -altr指令功能,要求使用链表储存,并且实现删除、添加、替换和按照时间排序。
具体代码:
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <time.h>
#include <unistd.h>
#include <sys/stat.h>
#include <errno.h>
#include <string.h>
#include <limits.h>
#include <pwd.h>
#include <grp.h>
#define max(a, b) ((a) > (b) ? (a) : (b))/* 字符串形式的stat信息 */
typedef struct
{/* 在头文件limits中定义了 #define NAME_MAX 255 */char strFname[NAME_MAX];/* 文件所有者 */char strUser[20];/* 文件所有者所在的组 */char strGroup[20];/* 文件字节数 */char strSize[16];/* 上一次文件修改的时间 */char strTime[13];/* 文件对应的类型 */char strMode[11];/* 文件的连接数 */char strLink[5];
} stStrInfo;/* 链表结构,因为需要预先获得目录里的所有项(为了控制格式化),但数目不确定,所以用链表保存 */
typedef struct
{stStrInfo stInfo;struct stListnode *pnext;
} stListnode;	int g_nLinkMaxlen = 0;
int g_nUserMaxlen = 0;
int g_nGroupMaxlen = 0;
int g_nSizeMaxlen = 0; // 字符串形式的最大长度,为了格式化构造字符串
int g_nArgL = 1;
int g_nArgA = 1;
int g_nArgM = 0;
int g_nArgD = 0;
int g_nArgI = 0; // 参数是否定义	// 解析选项
void analyse_opt(int argc, char *argv[]);
// 构造文件的详细信息
void build_line(stStrInfo *stat_strbuf, char *fmtstrbuf);
// 打印目录信息
void print_dir_info(const char *dir);
// 获得文件信息的str形式
void get_stat_str(const struct stat *stbuf, const char *fname, stStrInfo *strbuf);int main(int argc, char *argv[])
{struct stat stBuf;stStrInfo stStrbuf;analyse_opt(argc, argv); // 解析选项printf("l:%d a:%d m:%d d:%d i:%d\n", g_nArgL, g_nArgA, g_nArgM, g_nArgD, g_nArgI);/* '.'可以代表当前路径 */print_dir_info(".");return 0;
}void analyse_opt(int argc, char *argv[])
{int nOpt;while ((nOpt = getopt(argc, argv, "lamdi")) != -1){switch (nOpt){case 'l':g_nArgL = 1;break;case 'a':g_nArgA = 1;break;case 'm':g_nArgM = 1;break;case 'd':g_nArgD = 1;break;case 'i':g_nArgI = 1;break;}}
}/* //获得文件信息的str形式 */
void get_stat_str(const struct stat *stbuf, const char *fname, stStrInfo *strbuf)
{/* 判断文件信息 *//* S_ISREG判断是否是常规文件,S_ISDIR判断是否是一个目录,S_ISBLK判断是否是一个连接,S_ISCHR判断是否是一个字符设备*/sprintf(strbuf->strMode, "%c%c%c%c%c%c%c%c%c%c",S_ISREG(stbuf->st_mode) ? '-' : (S_ISDIR(stbuf->st_mode) ? 'd' : (S_ISBLK(stbuf->st_mode) ? 'b' : (S_ISCHR(stbuf->st_mode) ? 'c' : 'l'))),/* S_IRUSR判断是否是允许文件所有者读操作 */(S_IRUSR & stbuf->st_mode) ? 'r' : '-',/* S_IWUSR判断是否是允许文件所有者写操作 */(S_IWUSR & stbuf->st_mode) ? 'w' : '-',/* S_IXUSR判断是否是允许文件所有者执行操作 */(S_IXUSR & stbuf->st_mode) ? 'x' : '-',/* S_IRGRP判断是否是允许文件所有者所在的组读操作 */(S_IRGRP & stbuf->st_mode) ? 'r' : '-',/* S_IWGRP判断是否是允许文件所有者所在的组写操作 */(S_IWGRP & stbuf->st_mode) ? 'w' : '-',/* S_IRGRP判断是否是允许文件所有者所在的组读操作 */(S_IXGRP & stbuf->st_mode) ? 'x' : '-',/* S_IROTH判断是否是允许其他用户读操作 */(S_IROTH & stbuf->st_mode) ? 'r' : '-',/* S_IWOTH判断是否是允许其他用户写操作 */(S_IWOTH & stbuf->st_mode) ? 'w' : '-',/* S_IXOTH判断是否是允许其他用户执行操作 */(S_IXOTH & stbuf->st_mode) ? 'x' : '-');/* 文件连接数 */sprintf(strbuf->strLink, "%ld", stbuf->st_nlink);g_nLinkMaxlen = max(g_nLinkMaxlen, strlen(strbuf->strLink));/* 文件所有者名称 */sprintf(strbuf->strUser, "%s", getpwuid(stbuf->st_uid)->pw_name);/* 文件所有者所在组 */sprintf(strbuf->strGroup, "%s", getgrgid(stbuf->st_gid)->gr_name);g_nUserMaxlen = max(g_nUserMaxlen, strlen(strbuf->strUser));g_nGroupMaxlen = max(g_nGroupMaxlen, strlen(strbuf->strGroup));/* 文件字节数 */sprintf(strbuf->strSize, "%ld", stbuf->st_size);g_nSizeMaxlen = max(g_nSizeMaxlen, strlen(strbuf->strSize));/* 文件上次修改时间 %b表示缩写的月份 %d表示第几天 %H表示24小时格式中的小时 %M表示分*/strftime(strbuf->strTime, 13, "%b %d %H:%M", localtime(&(stbuf->st_mtime)));/* 文件名称 */sprintf(strbuf->strFname, "%s", fname);
}/* 对链表进行排序 */
void SortList(stListnode *sthead_Listnode)
{stListnode *pt1 = NULL;stListnode *pt2 = NULL;for (pt1 = sthead_Listnode->pnext, pt2 = pt1->pnext;pt2 != NULL;pt1 = pt1->pnext, pt2 = pt1->pnext){for (; pt2 != NULL; pt2 = pt2->pnext){if (strcmp((pt1->stInfo.strTime), (pt2->stInfo.strTime)) > 0){/* LinkStNode*必须初始化时便赋 */stListnode stLinkInfo;stLinkInfo.stInfo = pt1->stInfo;pt1->stInfo = pt2->stInfo;pt2->stInfo = stLinkInfo.stInfo;}}}
}  /* 对链表进行删除操作 */
void DeleteList(stListnode *sthead_Listnode)
{stListnode *pt1 = sthead_Listnode;stListnode *pt2 = NULL;char strFileinfo[20];memset(strFileinfo, 0, sizeof(strFileinfo));printf("输入需要删除的文件名字\n");scanf("%s", strFileinfo);/* 遍历链表找到要删除的数 或 p为NULL */while (pt1){if (strcmp(pt1->stInfo.strFname, strFileinfo) == 0){break;}pt2 = pt1; // 保存当前指针的指向pt1 = pt1->pnext;}if (pt1 != NULL){pt2->pnext = pt1->pnext;}else{printf("未找到该文件\n");}
}/* 对链表进行修改操作 */
void modityList(stListnode *sthead_Listnode)
{stListnode *pt1 = sthead_Listnode;char strFileinfo[20];memset(strFileinfo, 0, sizeof(strFileinfo));printf("输入需要修改的文件名字\n");scanf("%s", strFileinfo);while (pt1){ // 遍历链表直至p->data 等于需要修改的数字 或p为NULLif (strcmp(pt1->stInfo.strFname, strFileinfo) == 0){break;}pt1 = pt1->pnext;}if (pt1 != NULL){char strModityinfo[20];memset(strModityinfo, 0, sizeof(strModityinfo));printf("修改为:");scanf("%s", strModityinfo);strcpy(pt1->stInfo.strFname, strModityinfo);}else{printf("未找到该文件\n");}
}/* 对链表进行增加操作 */
void increaseList(stListnode *sthead_Listnode)
{stListnode *pt1 = sthead_Listnode;stListnode *pt2 = NULL; // 定义pt2为需增加的新节点char strFileinfo[20];memset(strFileinfo, 0, sizeof(strFileinfo));printf("请输入增加在哪个文件的后面\n");scanf("%s", strFileinfo);while (pt1){if (strcmp(pt1->stInfo.strFname, strFileinfo) == 0){break;}pt1 = pt1->pnext;}if (pt1 != NULL){pt2 = (stListnode *)malloc(sizeof(stListnode));printf("增加的文件名称\n");scanf("%s", pt2->stInfo.strFname);pt2->pnext = pt1->pnext;pt1->pnext = pt2;}else{printf("未找到该文件\n");}return;
}void print_dir_info(const char *dir)
{g_nGroupMaxlen = 0;g_nLinkMaxlen = 0;g_nUserMaxlen = 0;g_nSizeMaxlen = 0;/* 打开目录函数 列出目录所有项 */DIR *pdir = opendir(dir);struct dirent *pdirent;struct stat stBuf;// 链表头(字符串形式的stat) */stListnode *sthead_Listnode = (stListnode *)(malloc(sizeof(stListnode)));stListnode *pstHead = sthead_Listnode;while ((pdirent = readdir(pdir)) != NULL){if ((pdirent->d_name)[0] != '.' || g_nArgA){// 是否显示隐藏文件char strPath[256];strcpy(strPath, dir);strcat(strPath, "/"); // d_name仅是个文件名而已/* 完整文件路径 */strcat(strPath, pdirent->d_name); // 需要加上完整路径/* 获取文件属性 */if (-1 == lstat(strPath, &stBuf)){// err_exit("lstat");return;}pstHead->pnext = (stListnode *)(malloc(sizeof(stListnode)));pstHead = pstHead->pnext;pstHead->pnext = NULL;get_stat_str(&stBuf, pdirent->d_name, &(pstHead->stInfo));}}/* 对链表进行排序 */SortList(sthead_Listnode);if (g_nArgD){/* 删除特定文件 */DeleteList(sthead_Listnode);}else if (g_nArgM){/* 修改特定文件 */modityList(sthead_Listnode);}/* 对链表进行增加操作 */else if (g_nArgI){/* 增加特定文件 */increaseList(sthead_Listnode);}// 输出信息链表的格式化内容pstHead = sthead_Listnode->pnext;while (pstHead){char strFmtstrbuf[256];build_line(&(pstHead->stInfo), strFmtstrbuf);/* puts(fmtstrbuf); */printf("%s\n", strFmtstrbuf);pstHead = pstHead->pnext;}stListnode *pstList = sthead_Listnode->pnext; // 释放链表int nMark = 0;while (pstList){free(sthead_Listnode);sthead_Listnode = pstList;pstList = pstList->pnext;}free(sthead_Listnode);
}
运行结果:

1、增加文件

2、删除操作

3、改变文件名称

4、显示文件详细内容

更多推荐

C语言实现实现Linux系统中ls

本文发布于:2024-03-07 17:38:22,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1718461.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:语言   系统   Linux   ls

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!