程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 更多關於編程 >> linux c模擬ls命令詳解

linux c模擬ls命令詳解

編輯:更多關於編程
    本篇文章是對linux中基於c模擬ls命令的實現方法進行了詳細的分析介紹,需要的朋友參考下   復制代碼 代碼如下:


    /*
    模擬ls命令,實現參數-tariRl.有些代碼重復出現,可改進
    可以在該程序的基礎上增加參數,該程序思路清晰,容易擴展
    */
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<sys/types.h>
    #include<unistd.h>
    #include<sys/stat.h>
    #include<dirent.h>
    #include<sys/ioctl.h>
    #include<pwd.h>
    #include<grp.h>
    #define LL (1<<0) /*帶l參數標志*/
    #define IL (1<<1) /*帶i參數標志*/
    #define RU (1<<2) /*帶R參數標志*/
    #define TL (1<<16) /*帶t參數標志*/
    #define AL (1<<17) /*帶a參數標志*/
    #define RL (1<<18) /*帶r參數標志*/
    #define LENGTH 500 /*字符串最大長度*/
    #define MAX_FILE_COUNT 500/*文件列表最大長度*/
    /*函數聲明*/
    void error(char* error_message,int line);
    void display(struct stat* stalist,char (*namelist)[LENGTH],int n,int mode);
    int file_list(char* path,struct stat* stalist,char (*namelist)[LENGTH],int mode);
    void display_simply(char (*namelist)[LENGTH],int n);
    void display_LL(struct stat * stalist,char (*namelist)[LENGTH],int n);
    void display_IL(struct stat * stalist,char (*namelist)[LENGTH],int n);
    void display_LL_IL(struct stat * stalist,char (*namelist)[LENGTH],int n);
    void display_RU(struct stat* stalist,char (*namelist)[LENGTH],int n,int mode);
    void display_RU_LL(struct stat * stalist,char (*namelist)[LENGTH],int n,int mode);
    void display_RU_IL(struct stat* stalist,char (*namelist)[LENGTH],int n,int mode);
    void display_RU_IL_LL(struct stat * stalist,char (*namelist)[LENGTH],int n,int mode);
    /*主函數*/
    int main(int argc,char **argv)
    {
    int i,j;
    /*mode的前16個位用來標志那些能影響顯示的參數,16位之後的位用來標志不影響輸出格式的參數。這個程序只用到了0-3位,16-18位,如果要在該程序的基礎上增加參數,可以用其他沒有使用的位。
    mode的第0位為1表示帶l參數,mode的第1位為1表示帶i參數,mode的第2位為1表示帶R參數,mode的第16位為1表示帶t參數,mode的第17位為1表示帶a參數,mode的第18位為1表示帶r參數*/
    int mode=0;
    char error_message[LENGTH]={0};/*錯誤信息*/
    char path[LENGTH]={0};/*路徑*/
    struct stat stalist[MAX_FILE_COUNT];/*文件詳細信息數組*/
    char namelist[MAX_FILE_COUNT][LENGTH];/*文件名數組*/
    int flag=0;/*判斷是否指定了目錄*/
    int count;/*文件個數*/
    /*解析參數*/
    for(i=1;i<argc;i++){
    if(argv[i][0]=='-'){/*如果是選項參數*/
    for(j=1;j<strlen(argv[i]);j++){
    if(argv[i][j]=='l')
    mode=mode|LL;
    else if(argv[i][j]=='i')
    mode=mode|IL;
    else if(argv[i][j]=='R')
    mode=mode|RU;
    else if(argv[i][j]=='r')
    mode=mode|RL;
    else if(argv[i][j]=='a')
    mode=mode|AL;
    else if(argv[i][j]=='t')
    mode=mode|TL;
    else{
    snprintf(error_message,LENGTH,"no option of %c",argv[i][j]);
    error(error_message,__LINE__);
    }
    }
    }else{/*參數為目錄或文件*/
    if(flag==1)
    error("can not specify more then two dir or file",__LINE__);
    else
    flag=1;
    if(argv[i][0]!='/'){/*相對路徑*/
    strcat(path,get_current_dir_name());
    strcat(path,"/");
    strncat(path,argv[i],strlen(argv[i]));
    }else/*絕對路徑*/
    strcpy(path,argv[i]);
    }
    }
    if(flag==0)/*未指定任何目錄或文件,則使用默認當前目錄*/
    strcat(path,get_current_dir_name());
    /*根據mode獲取指定目錄下的文件*/
    count=file_list(path,stalist,namelist,mode);

    /*根據mode顯示文件*/
    display(stalist,namelist,count,mode);
    return 0;
    }
    /*獲取文件列表*/
    int file_list(char* path,struct stat* stalist,char (*namelist)[LENGTH],int mode)
    {
    int i=0,index,j,k;
    DIR *dir;
    struct dirent *ptr;
    char str[LENGTH];
    char nametemp[LENGTH];
    struct stat statemp;
    if(stat(path,&stalist[0])<0){
    // puts(path);
    error("the specify file is not exist",__LINE__);
    }
    if(S_ISDIR(stalist[0].st_mode)){/*如果該路徑指向的是一個目錄*/
    if((dir=opendir(path))==NULL){/*打開目錄*/
    sprintf(str,"can not open %s",path);
    error(str,__LINE__);
    }
    chdir(path);/*改變當前工作目錄到path*/
    i=0;
    while((ptr=readdir(dir))!=NULL){/*依次讀取目錄下的所有文件*/
    if(ptr->d_name[0]=='.' && !(mode & AL))/*忽略隱藏文件*/
    continue;
    /*按字母順序插入到stalist數組及namelist數組*/
    for(j=i;j>0;j--){
    if(strcmp(ptr->d_name,namelist[j-1])>0)
    break;
    }
    for(k=i;k>j;k--){
    strcpy(namelist[k],namelist[k-1]);
    stalist[k]=stalist[k-1];
    }
    strcpy(namelist[j],ptr->d_name);
    stat(ptr->d_name,&stalist[j]);
    i++;
    if(i==MAX_FILE_COUNT)
    error("file count beyond MAX_FILE_COUNT",__LINE__);
    }
    closedir(dir);
    }else{
    j=strlen(path)-1;
    while(j>=0 && path[j]!='/'){
    j--;
    }
    if(j<0)
    error("path error",__LINE__);
    j++;
    k=0;
    while(path[j]){
    namelist[0][k]=path[j];
    j++;
    k++;
    }
    namelist[0][k]=0;
    return 1;
    }
    if(mode & TL){/*按文件修改時間排序*/
    for(j=0;j<i;j++){
    index=j;
    for(k=j+1;k<i;k++)
    if(stalist[index].st_mtime<stalist[k].st_mtime){
    index=k;
    }
    statemp=stalist[j];
    stalist[j]=stalist[index];
    stalist[index]=statemp;
    strcpy(nametemp,namelist[j]);
    strcpy(namelist[j],namelist[index]);
    strcpy(namelist[index],nametemp);
    }
    }
    if(mode & RL){/*反序排列*/
    for(j=0;j<i/2;j++){
    strcpy(nametemp,namelist[j]);
    strcpy(namelist[j],namelist[i-j-1]);
    strcpy(namelist[i-j-1],nametemp);
    statemp=stalist[j];
    stalist[j]=stalist[i-j-1];
    stalist[i-j-1]=statemp;
    }
    }
    return i;
    }
    /*根據mode選擇不同的函數進行顯示*/
    void display(struct stat* stalist,char (*namelist)[LENGTH],int n,int mode)
    {
    /*使mode的高16位為0*/
    int m = mode & ((1<<16)-1);
    switch(m){
    case 0:
    display_simply(namelist,n);
    break;
    case 1:
    display_LL(stalist,namelist,n);
    break;
    case 2:
    display_IL(stalist,namelist,n);
    break;
    case 3:
    display_LL_IL(stalist,namelist,n);
    break;
    case 4:
    display_RU(stalist,namelist,n,mode);
    break;
    case 5:
    display_RU_LL(stalist,namelist,n,mode);
    break;
    case 6:
    display_RU_IL(stalist,namelist,n,mode);
    break;
    case 7:
    display_RU_IL_LL(stalist,namelist,n,mode);
    break;
    }
    }
    /*不帶顯示選項,簡單顯示文件名*/
    void display_simply(char (*namelist)[LENGTH],int n)
    {
    int i,maxlength=0,cols;
    struct winsize ts;
    for(i=0;i<n;i++)
    if(strlen(namelist[i])>maxlength)
    maxlength=strlen(namelist[i]);
    /*獲取終端的大小*/
    ioctl(STDIN_FILENO,TIOCGWINSZ,&ts);
    cols=ts.ws_col;
    cols/=(maxlength+1);
    //lines=ts.ws_row;
    for(i=0;i<n;i++){
    if(i!=0 && i%cols==0)
    puts("");
    printf("%*s",-(maxlength+1),namelist[i]);
    }
    putchar('n');
    }
    /*-l 參數,顯示詳細文件信息*/
    void display_LL(struct stat * stalist,char (*namelist)[LENGTH],int n)
    {
    int i,mode;
    char* str;
    for(i=0;i<n;i++){
    mode=stalist[i].st_mode;
    if(S_ISDIR(mode))
    printf("d");
    else
    printf("-");
    if(mode & (1<<8))
    printf("r");
    else
    printf("-");
    if(mode & (1<<7))
    printf("w");
    else
    printf("-");
    if(mode & (1<<6))
    printf("x");
    else
    printf("-");
    if(mode & (1<<5))
    printf("r");
    else
    printf("-");
    if(mode & (1<<4))
    printf("w");
    else
    printf("-");
    if(mode & (1<<3))
    printf("x");
    else
    printf("-");
    if(mode & (1<<2))
    printf("r");
    else
    printf("-");
    if(mode & (1<<1))
    printf("w");
    else
    printf("-");
    if(mode & (1<<0))
    printf("x");
    else
    printf("-");
    printf(" %-3d",stalist[i].st_nlink);
    printf(" %-6s",getpwuid(stalist[i].st_uid)->pw_name);
    printf(" %-6s",getgrgid(stalist[i].st_gid)->gr_name);
    printf(" %-10d",stalist[i].st_size);
    str=ctime(&stalist[i].st_mtime);
    str[strlen(str)-2]=0;
    printf(" %s",str);
    printf(" %sn",namelist[i]);
    }
    }
    /*-i 參數,顯示文件名及節點號*/
    void display_IL(struct stat* stalist,char (*namelist)[LENGTH],int n)
    {
    int i,maxlength=0,cols;
    struct winsize ts;
    for(i=0;i<n;i++)
    if(strlen(namelist[i])>maxlength)
    maxlength=strlen(namelist[i]);
    /*獲取終端的大小*/
    ioctl(STDIN_FILENO,TIOCGWINSZ,&ts);
    cols=ts.ws_col;
    cols/=(maxlength+9);
    //lines=ts.ws_row;

    for(i=0;i<n;i++){
    if(i!=0 && i%cols==0)
    puts("");
    printf("%-8d ",stalist[i].st_ino);
    printf("%*s",-(maxlength+1),namelist[i]);
    }
    putchar('n');
    }
    /*-li 參數,顯示詳細文件信息和節點號*/
    void display_LL_IL(struct stat * stalist,char (*namelist)[LENGTH],int n)
    {
    int i,mode;
    char* str;
    for(i=0;i<n;i++){
    printf("%-8d ",stalist[i].st_ino);
    mode=stalist[i].st_mode;
    if(S_ISDIR(mode))
    printf("d");
    else
    printf("-");
    if(mode & (1<<8))
    printf("r");
    else
    printf("-");
    if(mode & (1<<7))
    printf("w");
    else
    printf("-");
    if(mode & (1<<6))
    printf("x");
    else
    printf("-");
    if(mode & (1<<5))
    printf("r");
    else
    printf("-");
    if(mode & (1<<4))
    printf("w");
    else
    printf("-");
    if(mode & (1<<3))
    printf("x");
    else
    printf("-");
    if(mode & (1<<2))
    printf("r");
    else
    printf("-");
    if(mode & (1<<1))
    printf("w");
    else
    printf("-");
    if(mode & (1<<0))
    printf("x");
    else
    printf("-");
    printf(" %-3d",stalist[i].st_nlink);
    printf(" %-6s",getpwuid(stalist[i].st_uid)->pw_name);
    printf(" %-6s",getgrgid(stalist[i].st_gid)->gr_name);
    printf(" %-10d",stalist[i].st_size);
    str=ctime(&stalist[i].st_mtime);
    str[strlen(str)-2]=0;
    printf(" %s",str);
    printf(" %sn",namelist[i]);

    }
    }
    /*-R 參數,簡單顯示所有文件,包括目錄下面的子目錄*/
    void display_RU(struct stat* stalist,char (*namelist)[LENGTH],int n,int mode)
    {
    int i,count;
    char path[LENGTH]={0},temp[LENGTH]={0};
    struct stat sta[MAX_FILE_COUNT];
    char name[MAX_FILE_COUNT][LENGTH];
    puts(get_current_dir_name());
    display_simply(namelist,n);
    putchar('n');
    strcpy(path,get_current_dir_name());

    for(i=0;i<n;i++){
    if(strcmp(namelist[i],".")==0 || strcmp(namelist[i],"..")==0)
    continue;
    if(S_ISDIR(stalist[i].st_mode)){
    strcpy(temp,path);
    strcat(path,"/");
    strcat(path,namelist[i]);
    count=file_list(path,sta,name,mode);
    display_RU(sta,name,count,mode);
    strcpy(path,temp);
    }
    }
    }
    /*-Rl 參數,顯示所有文件,包括目錄下面的子目錄的詳細信息*/
    void display_RU_LL(struct stat * stalist,char (*namelist)[LENGTH],int n,int mode)
    {
    int i,count;
    char path[LENGTH]={0},temp[LENGTH]={0};
    struct stat sta[MAX_FILE_COUNT];
    char name[MAX_FILE_COUNT][LENGTH];
    puts(get_current_dir_name());
    display_LL(stalist,namelist,n);
    putchar('n');
    strcpy(path,get_current_dir_name());

    for(i=0;i<n;i++){
    if(strcmp(namelist[i],".")==0 || strcmp(namelist[i],"..")==0)
    continue;
    if(S_ISDIR(stalist[i].st_mode)){
    strcpy(temp,path);
    strcat(path,"/");
    strcat(path,namelist[i]);
    count=file_list(path,sta,name,mode);
    display_RU_LL(sta,name,count,mode);
    strcpy(path,temp);
    }
    }
    }
    /*-Ri 參數,簡單顯示所有文件,包括目錄下的子目錄,及節點號*/
    void display_RU_IL(struct stat* stalist,char (*namelist)[LENGTH],int n,int mode)
    {
    int i,count;
    char path[LENGTH]={0},temp[LENGTH]={0};
    struct stat sta[MAX_FILE_COUNT];
    char name[MAX_FILE_COUNT][LENGTH];
    puts(get_current_dir_name());
    display_IL(stalist,namelist,n);
    putchar('n');
    strcpy(path,get_current_dir_name());

    for(i=0;i<n;i++){
    if(strcmp(namelist[i],".")==0 || strcmp(namelist[i],"..")==0)
    continue;
    if(S_ISDIR(stalist[i].st_mode)){
    strcpy(temp,path);
    strcat(path,"/");
    strcat(path,namelist[i]);
    count=file_list(path,sta,name,mode);
    display_RU_IL(sta,name,count,mode);
    strcpy(path,temp);
    }
    }
    }
    /*-Ril 參數,顯示所有文件,包括目錄下面的子目錄的詳細信息,及節點號*/
    void display_RU_IL_LL(struct stat * stalist,char (*namelist)[LENGTH],int n,int mode)
    {
    int i,count;
    char path[LENGTH]={0},temp[LENGTH]={0};
    struct stat sta[MAX_FILE_COUNT];
    char name[MAX_FILE_COUNT][LENGTH];
    puts(get_current_dir_name());
    display_LL_IL(stalist,namelist,n);
    putchar('n');
    strcpy(path,get_current_dir_name());

    for(i=0;i<n;i++){
    if(strcmp(namelist[i],".")==0 || strcmp(namelist[i],"..")==0)
    continue;
    if(S_ISDIR(stalist[i].st_mode)){
    strcpy(temp,path);
    strcat(path,"/");
    strcat(path,namelist[i]);
    count=file_list(path,sta,name,mode);
    display_RU_IL_LL(sta,name,count,mode);
    strcpy(path,temp);
    }
    }
    }
    //錯誤處理函數
    void error(char* error_message,int line)
    {
    char str[5];
    sprintf(str,"%d:",line);
    strcat(str,error_message);
    perror(str);
    exit(EXIT_FAILURE);
    }

    1. 上一頁:
    2. 下一頁:
    Copyright © 程式師世界 All Rights Reserved