编程实现Linux下的ls -l

头文件

#ifndef __FUNC_H__
#define __FUNC_H__

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
#include <pwd.h>
#include <grp.h>

#define ENT_CNT 128    
#define FILE_LEN 256

int get_file_name(DIR* pdir,char* dirname ,char names[][FILE_LEN]);
void str_sort(char arr[][FILE_LEN], int cnt);
void show_ent(char name[][FILE_LEN], int cnt);
void mode_to_str(mode_t mode, char* dest);
char* time_format(char* src);

#endif

主函数

/*************************************************************************
  > File Name: func.c
  > Author: KrisChou
  > Mail: zhoujx0219@163.com 
  > Created Time: Tue 19 Aug 2014 02:31:34 PM CST
 ************************************************************************/
#include "func.h"

int main(int argc, char* argv[])
{
    DIR* pdir ;
    struct dirent *pent ; 
    
    char file_names[ENT_CNT][FILE_LEN] ;
    int cnt ; //所遍历目录子项的个数
    char pold[128]="";  //记录程序原来的工作路径
    char pnew[128]=".";  //记录所需遍历目录的绝对路径,使用stat获取文件信息需要绝对路径(除非程序遍历当前目录)
    getcwd(pold, 128); 
    if(argc == 2)
    {
        pdir = opendir(argv[1]);
        chdir(argv[1]);
        getcwd(pnew, 128);
        chdir(pold);
    }else if(argc == 1)
    {
        pdir = opendir(".");

    }else 
    {
        printf("USAGE: EXE DIR \n");
        exit(1);
    }

    if(pdir == NULL)
    {
        perror("opendir");
        exit(1);
    }
    cnt = get_file_names(pdir,pnew ,file_names); //将每一项的 绝对路径(pnew) + filename 存入数组,以便stat获取文件信息
     str_sort(file_names, cnt);
    show_ent(file_names, cnt);
    return 0 ;
}

1. get_file_name

/*************************************************************************
  > File Name: ./src/get_file_name.c
  > Author: KrisChou
  > Mail:zhoujx0219@163.com 
  > Created Time: Tue 19 Aug 2014 03:03:23 PM CST
 ************************************************************************/

#include "func.h"
int get_file_names(DIR* pdir, char* dirname, char names[][FILE_LEN])
{
    struct dirent* pent ;
    int cnt = 0 ;
    while( (pent = readdir(pdir)) != NULL )
    {
        if(strncmp(pent ->d_name, ".", 1) == 0 || strncmp(pent ->d_name, "..", 2) == 0)
        {
            continue ;
        }
        strcpy(names[cnt],dirname);
        strcat(names[cnt], "/");
        strcat(names[cnt], pent -> d_name);
        cnt ++ ;
    }
    closedir(pdir);
    return cnt ;

}

2. str_sort

/*************************************************************************
    > File Name: ./src/str_sort.c
    > Author: KrisChou
    > Mail:zhoujx0219@163.com 
    > Created Time: Tue 19 Aug 2014 03:19:05 PM CST
 ************************************************************************/
#include "func.h"

static int my_cmp(const void* left, const void* right )
{
    return strcmp((char* )left , (char*)right);
}

void str_sort(char arr[][FILE_LEN], int cnt)
{
    qsort(arr, cnt, FILE_LEN, my_cmp);
}

3. show_ent

/*************************************************************************
  > File Name: show_ent.c
  > Author: KrisChou
  > Mail:zhoujx0219@163.com 
  > Created Time: Tue 19 Aug 2014 02:36:17 PM CST
 ************************************************************************/
#include "func.h"

void show_ent(char name[][FILE_LEN], int cnt)
{
    struct stat my_stat ;
    char buf[11]="";
    char *pstr ;
    int index ;
    for(index = 0; index < cnt; index ++)
    {
        memset(&my_stat, 0, sizeof(my_stat));
        if( stat(name[index], &my_stat) == -1 )
        {
            perror("stat");
            exit (1);
        }
        mode_to_str(my_stat.st_mode, buf);
        pstr = ctime(&(my_stat.st_atime));//Mon Aug 18 14:37:40 2014
        pstr = time_format(pstr);
        printf("%10s.%2d%7s%7s%5d%13s %s\n",buf, my_stat.st_nlink, getpwuid(my_stat.st_uid)->pw_name, getgrgid(my_stat.st_gid) ->gr_name, my_stat.st_size, pstr,name[index]);

    }
}

3.1 mode_to_str

/*************************************************************************
  > File Name: mode_to_str.c
  > Author: KrisChou
  > Mail:zhoujx0219@163.com 
  > Created Time: Tue 19 Aug 2014 02:32:33 PM CST
 ************************************************************************/
#include "func.h"

void mode_to_str(mode_t mode, char* dest)
{
    memset(dest,'-',10);
    if(S_ISDIR(mode))
    {
        dest[0]='d';
    }
    if(S_ISREG(mode))
    {
        dest[0]='-';
    }

    if(mode & S_IRUSR)
    {
        dest[1] = 'r' ;
    }
    if(mode & S_IWUSR)
    {
        dest[2] = 'w' ;
    }
    if(mode & S_IXUSR)
    {
        dest[3] = 'x' ;
    }
    if(mode & S_IRGRP)
    {
        dest[4] = 'r' ;
    }
    if(mode & S_IWGRP)
    {
        dest[5] = 'w' ;
    }
    if(mode & S_IXGRP)
    {
        dest[6] = 'x' ;
    }
    if(mode & S_IROTH)
    {
        dest[7] = 'r' ;
    }
    if(mode & S_IWOTH)
    {
        dest[8] = 'w' ;
    }
    if(mode & S_IXOTH)
    {
        dest[9] = 'x' ;
    }
}

3.2 time_format

/*************************************************************************
    > File Name: time_format.c
    > Author: KrisChou
    > Mail:zhoujx0219@163.com 
    > Created Time: Tue 19 Aug 2014 02:35:12 PM CST
 ************************************************************************/
#include "func.h"

char* time_format(char* src)
{
    int index = strlen(src) - 1 ;
    for(; src[index]!=':'; index -- )
    {
        
    }
    src[index] = '\0' ;
    return src + 4 ;
}

Makefile

SRC_DIR := ./src
INC_DIR := ./include
EXE_DIR := ./bin
OBJECTS := $(wildcard $(SRC_DIR)/*.c)
INCLUDES :=$(wildcard $(INC_DIR)/*.h)
CC := gcc
FLAGS := -o
$(EXE_DIR)/main : $(OBJECTS) $(INCLUDES)
    $(CC) $(FLAGS) $@ $(OBJECTS) -I$(INC_DIR)
 

转载于:https://www.cnblogs.com/jianxinzhou/p/3923521.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现ls -l命令的关键是要读取当前目录下的文件和文件夹的信息,并将其格式化输出。下面是一个简单的C语言程序,实现了类似于ls -l的功能: ```c #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <dirent.h> #include <sys/stat.h> #include <unistd.h> #include <pwd.h> #include <grp.h> #include <time.h> int main(int argc, char *argv[]) { DIR *dp; struct dirent *entry; struct stat statbuf; struct passwd *pwd; struct group *grp; char date[20]; if ((dp = opendir(".")) == NULL) { fprintf(stderr, "Cannot open directory.\n"); exit(1); } while ((entry = readdir(dp)) != NULL) { if (entry->d_name[0] == '.') continue; if (lstat(entry->d_name, &statbuf) < 0) continue; printf((S_ISDIR(statbuf.st_mode)) ? "d" : "-"); printf((statbuf.st_mode & S_IRUSR) ? "r" : "-"); printf((statbuf.st_mode & S_IWUSR) ? "w" : "-"); printf((statbuf.st_mode & S_IXUSR) ? "x" : "-"); printf((statbuf.st_mode & S_IRGRP) ? "r" : "-"); printf((statbuf.st_mode & S_IWGRP) ? "w" : "-"); printf((statbuf.st_mode & S_IXGRP) ? "x" : "-"); printf((statbuf.st_mode & S_IROTH) ? "r" : "-"); printf((statbuf.st_mode & S_IWOTH) ? "w" : "-"); printf((statbuf.st_mode & S_IXOTH) ? "x" : "-"); printf(" %2lu", statbuf.st_nlink); if ((pwd = getpwuid(statbuf.st_uid)) != NULL) { printf(" %s", pwd->pw_name); } else { printf(" %d", statbuf.st_uid); } if ((grp = getgrgid(statbuf.st_gid)) != NULL) { printf(" %s", grp->gr_name); } else { printf(" %d", statbuf.st_gid); } strftime(date, 20, "%b %d %H:%M", localtime(&statbuf.st_mtime)); printf(" %s", date); printf(" %s\n", entry->d_name); } closedir(dp); return 0; } ``` 这个程序使用了许多系统调用和库函数,比如opendir、readdir、lstat、getpwuid、getgrgid等等。它首先打开当前目录("."),然后循环读取目录下的每个文件和文件夹的信息,使用lstat函数获取文件的详细信息,再利用各种库函数将这些信息格式化输出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值