C写的实现wc和ls函数

以下是用linux C写的实现wc功能的函数

#include

#define BEGIN 1;

int main(int argc, char *argv[])
{
    int characters, lines, words, state;
    char c;

    state = characters = lines = words = 0;
    while((c = getchar()) != '0') {
        characters++;
        if(c == '\n') {
            lines++;
            state = 0;
            continue;
        } else if(c == ' ') {
            state = 0;
            continue;
        } else if(c == '\t') {
            state = 0;
            continue;
        } else {
            if(state == 0) {
                state = BEGIN;
                words++;
            }
            continue;
        }
    }

    printf("%d characters. %d words. %d lines.\n", characters, words, lines);
}

以下是用linux C写的实现ls部分功能的函数。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include


//用lstat函数获取文件的类型
int get_mode(char *file)
{
    struct stat buf;
    char *ptr;

    if(lstat(file, &buf) < 0)
    {
        printf("error\n!");
    }
    switch(S_IFMT&buf.st_mode)
    {
        case S_IFREG:ptr = "-";break;
        case S_IFDIR:ptr = "d";break;
        case S_IFCHR:ptr = "c";break;
        case S_IFBLK:ptr = "b";break;
        case S_IFIFO:ptr = "f";break;
        case S_IFLNK:ptr = "l";break;
        case S_IFSOCK:ptr = "s";break;
        default:ptr = "UNKNOW";
    }

    printf("%s", ptr);

    return 0;
}

//用stat获取文件拥有者,用户组和其他组的权限
int get_rwx(char *file)
{
    struct stat buf;

    if(stat(file, &buf) == -1)
    {
        perror("stat \n");
        return 0;   
    }

    //文件拥有者的权限获取
    if(S_IRUSR&buf.st_mode) {
        printf("r");   
    } else {
        printf("-");
    }
    if(S_IWUSR&buf.st_mode) {
        printf("w");   
    } else {
        printf("-");
    }
    if(S_IXUSR&buf.st_mode) {
        printf("x");   
    } else {
        printf("-");
    }
   
    //文件用户组的权限获取
    if(S_IRGRP&buf.st_mode) {
        printf("r");   
    } else {
        printf("-");
    }
    if(S_IWGRP&buf.st_mode) {
        printf("w");   
    } else {
        printf("-");
    }
    if(S_IXGRP&buf.st_mode) {
        printf("x");   
    } else {
        printf("-");
    }

    //文件其他组的权限获取
    if(S_IROTH&buf.st_mode) {
        printf("r");   
    } else {
        printf("-");
    }
    if(S_IWOTH&buf.st_mode) {
        printf("w");   
    } else {
        printf("-");
    }
    if(S_IXOTH&buf.st_mode) {
        printf("x");   
    } else {
        printf("-");
    }

    return 0;
}

//获取文件的大小
long get_size(char *file)
{
    struct stat buf;
    long n;

    stat(file, &buf);   
    n = buf.st_size;   
   
    return n;
}

//获取文件的修改时间
int get_time(char *file, char *ch)
{
    struct stat buf;

    stat(file, &buf);
    strcpy(ch, ctime(&buf.st_mtime));   
    ch[strlen(ch) - 1] = '\0';

    return 0;
}

//文件的硬链接数目,并且打印出来
int get_nlink(char *file)
{
    struct stat buf;

    stat(file, &buf);
    printf(" %d", buf.st_nlink);
   
    return 0;
}

//获取文件拥有者和用户组的name
int get_name(char *file)
{
    struct stat buf;
    char name1[20], name2[20];

    stat(file, &buf);
    strcpy(name1, getpwuid(buf.st_uid)->pw_name);
    strcpy(name2, getpwuid(buf.st_gid)->pw_name);
    printf(" %s %s", name1, name2);

    return 0;
}

//浏览文件夹的内容
struct dirent **scan_dir(int *n)
{
    struct dirent **namelist;
   
    (*n) = scandir(".", &namelist, 0, alphasort);
    if ((*n) < 0)
        perror("scandir");

    return namelist;
}

//实现ls不带参数的命令
int no_ls()
{
    struct dirent **namelist;
    int i, n;
    long all_size = 0, size;

    namelist = scan_dir(&n);
    for(i = 0; i < n; i++) {
        if(namelist[i]->d_name[0] != '.') {
            printf("%-s  ", namelist[i]->d_name);
        }
       
        free(namelist[i]);
    }
    printf("\n");
    free(namelist);

    return 0;
}

//实现ls -l的命令
int l_ls()
{
    struct dirent **namelist;
    int n, i;
    long all_size = 0, size;
    char ch[40] = {0};

    namelist = scan_dir(&n);
   
    //得到文件总的大小
    for(i = 0; i < n; i++) {
        if(namelist[i]->d_name[0] != '.') {
            size = get_size(namelist[i]->d_name);
            all_size += size;
        }
    }

    //打印信息
    printf("总用量:%ld\n", all_size);
    for(i = 0; i < n; i++) {
        if(namelist[i]->d_name[0] != '.') {
            get_mode(namelist[i]->d_name);
            get_rwx(namelist[i]->d_name);
            get_nlink(namelist[i]->d_name);
           
            get_name(namelist[i]->d_name);

            printf(" %5ld", get_size(namelist[i]->d_name));
            get_time(namelist[i]->d_name, ch);
            printf(" %s", ch);
            printf(" %s", namelist[i]->d_name);
            printf("\n");
        }
        free(namelist[i]);
    }
    free(namelist);

    return 0;
}

//实现ls -al的命令
int al_ls()
{
    struct dirent **namelist;
    int n, i;
    long all_size = 0, size;
    char ch[40] = {0};
   
    namelist = scan_dir(&n);
   
    //得到文件总的大小
    for(i = 0; i < n; i++) {
        size = get_size(namelist[i]->d_name);
        all_size += size;
    }

    printf("总用量:%ld\n", all_size);
    for(i = 0; i < n; i++) {
        get_mode(namelist[i]->d_name);
        get_rwx(namelist[i]->d_name);
        get_nlink(namelist[i]->d_name);   

        get_name(namelist[i]->d_name);

        all_size += size;
        printf(" %5ld", get_size(namelist[i]->d_name));
        get_time(namelist[i]->d_name, ch);
        printf(" %s", ch);
        printf(" %s", namelist[i]->d_name);
        printf("\n");
        free(namelist[i]);
    }
    free(namelist);

    return 0;
}

//实现ls -a的命令
int a_ls()
{
    struct dirent **namelist;
    int i, n;

    namelist = scan_dir(&n);
    for(i = 0; i < n; i++) {
        printf("%-s  ", namelist[i]->d_name);
        free(namelist[i]);
    }
    printf("\n");
    free(namelist);

    return 0;
}

//实现ls -A的命令
int A_ls()
{
    struct dirent **namelist;
    int i, n, test1, test2;

    namelist = scan_dir(&n);
    for(i = 0; i < n; i++) {
        test1 = strcmp(".", namelist[i]->d_name) == 0;
        test2 = strcmp("..", namelist[i]->d_name) == 0;
        if(test1 || test2){
            free(namelist[i]);
            continue;
        }
        printf("%-s  ", namelist[i]->d_name);
        free(namelist[i]);
    }
    printf("\n");
    free(namelist);

    return 0;
}

//浏览指定目录下的文件
int dir_ls(char *name)
{
    struct dirent **namelist;
    char file[20] = {0};
    int i, n;

    strcpy(file, "./");
    strcat(file, name);

    printf("%s\n", name);
    n = scandir(file, &namelist, 0, alphasort);
    for(i = 0; i < n; i++) {
        if(namelist[i]->d_name[0] == '.') {
            free(namelist[i]);
            continue;
        }
        printf("%-s  ", namelist[i]->d_name);
        free(namelist[i]);
    }
    printf("\n");
    free(namelist);

    return 0;
}

//实现多个输入文件时的输出name_ls
int name_ls(int argc, char **argv)
{
    int i;
    struct stat buf;

    for(i = 1; i < argc; i++) {
        if(lstat(argv[i], &buf) < 0) {
            perror("lstat:\n");
        }

        switch(S_IFMT&buf.st_mode) {
            case S_IFDIR:dir_ls(argv[i]);break;
            default:file_ls(argv[i]);
        }
    }

    return 0;
}

//实现file_ls
int file_ls(char *file)
{
    int fd;
    struct stat buf;
   
    if(lstat(file, &buf) < 0) {
        perror("lstat:\n");
        return 0;
    }
    switch(S_IFMT&buf.st_mode) {
        case S_IFDIR:dir_ls(file);return 0;
    }

    if((fd = open(file, O_RDONLY)) == -1) {
        printf("没有找到%s文件!\n", file);
    } else {
        close(fd);
        printf("%s\n", file);
    }

    return 0;
}

//实现mylist
int mylist(char *option)
{
    if(strcmp(option, "-l") == 0) {
        l_ls();
    } else if(strcmp(option, "-al") == 0 || strcmp(option, "-la") == 0) {
        al_ls();   
    } else if(strcmp(option, "-a") == 0) {
        a_ls();
    } else if(strcmp(option, "-A") == 0) {
        A_ls();
    } else {
        file_ls(option);
    }

    return 0;
}

//主函数
int main(int argc, char *argv[])
{
    if(argc == 1) {
        no_ls();   
    } else if(argc == 2) {
        mylist(argv[1]);   
    } else if(argc > 2) {
        name_ls(argc, argv);
    } else {
        perror("Input error!\n");
    }

    return 0;
}



<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
阅读(3795) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~
评论热议
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Linux 中,多管道可以使用 pipe() 系统调用实现,具体实现步骤如下: 1. 创建多个管道 ```c int fd[2][2]; // fd[i][0] 代表第 i 个管道的读端,fd[i][1] 代表第 i 个管道的端 for (int i = 0; i < n; i++) { if (pipe(fd[i]) == -1) { perror("pipe"); exit(EXIT_FAILURE); } } ``` 2. fork 出多个子进程,并将它们的标准输入、标准输出连接到管道中 ```c int pid; for (int i = 0; i < n; i++) { pid = fork(); if (pid == -1) { perror("fork"); exit(EXIT_FAILURE); } else if (pid == 0) { // 子进程 if (i == 0) { // 第一个子进程 dup2(fd[i][1], STDOUT_FILENO); // 将标准输出连接到 fd[i][1] 上 close(fd[i][0]); // 关闭其它管道 for (int j = 1; j < n; j++) { close(fd[j][0]); close(fd[j][1]); } } else if (i == n - 1) { // 最后一个子进程 dup2(fd[i-1][0], STDIN_FILENO); // 将标准输入连接到 fd[i-1][0] 上 close(fd[i][0]); // 关闭其它管道 for (int j = 0; j < n - 1; j++) { close(fd[j][0]); close(fd[j][1]); } } else { // 中间的子进程 dup2(fd[i-1][0], STDIN_FILENO); // 将标准输入连接到 fd[i-1][0] 上 dup2(fd[i][1], STDOUT_FILENO); // 将标准输出连接到 fd[i][1] 上 for (int j = 0; j < n; j++) { if (j != i - 1 && j != i) { close(fd[j][0]); close(fd[j][1]); } } } execlp(cmd[i][0], cmd[i], NULL); // 执行命令 perror("execlp"); // execlp 函数不返回,如果返回则说明出错了 exit(EXIT_FAILURE); } else { // 父进程 if (i == 0) { close(fd[i][1]); // 关闭端 } else if (i == n - 1) { close(fd[i-1][0]); // 关闭读端 } else { close(fd[i-1][0]); close(fd[i][1]); } } } ``` 3. 等待子进程结束 ```c for (int i = 0; i < n; i++) { wait(NULL); } ``` 完整的代码实现如下: ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> int main() { char *cmd[3][3] = { {"ls", "-al", NULL}, {"grep", "test", NULL}, {"wc", "-l", NULL} }; int n = 3; // 管道数量 int fd[2][2]; // fd[i][0] 代表第 i 个管道的读端,fd[i][1] 代表第 i 个管道的端 for (int i = 0; i < n; i++) { if (pipe(fd[i]) == -1) { perror("pipe"); exit(EXIT_FAILURE); } } int pid; for (int i = 0; i < n; i++) { pid = fork(); if (pid == -1) { perror("fork"); exit(EXIT_FAILURE); } else if (pid == 0) { if (i == 0) { dup2(fd[i][1], STDOUT_FILENO); close(fd[i][0]); for (int j = 1; j < n; j++) { close(fd[j][0]); close(fd[j][1]); } } else if (i == n - 1) { dup2(fd[i-1][0], STDIN_FILENO); close(fd[i][0]); for (int j = 0; j < n - 1; j++) { close(fd[j][0]); close(fd[j][1]); } } else { dup2(fd[i-1][0], STDIN_FILENO); dup2(fd[i][1], STDOUT_FILENO); for (int j = 0; j < n; j++) { if (j != i - 1 && j != i) { close(fd[j][0]); close(fd[j][1]); } } } execlp(cmd[i][0], cmd[i], NULL); perror("execlp"); exit(EXIT_FAILURE); } else { if (i == 0) { close(fd[i][1]); } else if (i == n - 1) { close(fd[i-1][0]); } else { close(fd[i-1][0]); close(fd[i][1]); } } } for (int i = 0; i < n; i++) { wait(NULL); } return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值