利用IO实现linux中的head -n 命令

利用io实现linux中的head -n 功能,将文件中的前n行数据输入到终端上。

1.标准IO实现

步骤:

(1)打开要进行操作的文件(只读)

(2)将输入的行数转换为数字,因为我们输入的是数字,但是系统会认为是字符,需要利用atoi进行转换

(3)循环读取文件中的字符,fgets读到‘\n’会结束,所以刚好一次读取一行,通过对行数进行循环,每读取一行就向终端写入一行

注意:可以在代码前边加入正确的输入格式,当输入错误的时候,进行提示。

// 标准io实现head -n 功能

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char const *argv[])
{
    if (argc != 3) // 判断是否输入了进行操作的文件与行数
    {
        printf("format:%s <filename> <int n>\n", argv[0]);
        return -1;
    }

    // 打开要操作的文件,只读打开
    FILE *fp;
    char buf[100] = "";
    fp = fopen(argv[1], "r");
    if (fp == NULL)
    {
        perror("fopen error");
        return -1;
    }

    // 字符转换为数字
    int n = atoi(argv[2]);

    // 循环读取打印到终端
    // 遇到'\n'结束,一次读一行
    for (int i = 1; i <= n; i++)
    {
        fgets(buf, 100, fp);
        fputs(buf, stdout);
        sleep(1);
    }

    // 关闭文件
    fclose(fp);

    return 0;
}

2.文件IO实现

思想:

文件io的写法,跟标准io比起来只在读取的时候有区别,标准io中fgets读取的时候,读取到行尾自动结束,但是文件io读取时无法一次性标准的读取一行。

所以我们换一个思路,一个字符一个字符的读取,然后对读取到的字符进行判断,当读取到'\n'的时候,就代表读取完了一整行,那么循环中的行数就加一,通过此方式控制循环的行数,可以做到输出固定的行数。

// 文件IO实现head -n 文件名 命令功能

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char const *argv[])
{
    if (argc != 3) // 判断是否输入了行数与进行操作的文件
    {
        printf("format:%s <hangshu> <destfile>\n", argv[0]);
        return -1;
    }

    // 只读打开文件
    int fd = open(argv[2], O_RDONLY);
    if (fd < 0)
    {
        printf("open err");
        return -1;
    }

    char buf[1000] = {};   // 存放读到的数据
    int n = atoi(argv[1]); // 确定打几行
    long s = 0;
    int len = 0;
    // 一个字符一个字符的读
    // 每读到一个'\n',就代表读到了行尾,行数加一,直到读取到n行
    while (len != n)
    {
        // 读取fp中 1个字符暂存在 buf中
        s = read(fd, buf, 1);
        if (buf[0] == '\n')
        {
            len++;
        }
        // 写入 buf 中 暂存的 s 个字符
        write(1, buf, s);
    }

    close(fd);

    return 0;
}

3.标准IO实现第二种写法

这个写法跟第二种是差不多肯定,只不过上一种是一次读取一个,一个一个的判断写入到终端,第二种方法是一次读取固定个数的字符,然后对读取的字符进行判断,如果一次性读取的字符串里包含换行符,那么就把换行符之前的字符串写入到终端,同时行数加一,如果一次性读取的字符串中没有换行符,那么就把这次读取到的字符全部写入到终端。

// 文件IO实现head -n 文件名 命令功能

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char const *argv[])
{
    if (argc != 3) // 判断是否输入了行数与进行操作的文件
    {
        printf("err,format:%s -n <filename>\n", argv[0]);
        return -1;
    }

    // 只读打开文件
    int fd = open(argv[2], O_RDONLY);
    if (fd < 0)
    {
        perror("open error");
        return -1;
    }

    // 暂存读取的数据
    char buf[32] = "";
    ssize_t r;
    int n = atoi(argv[1]);

    int h = 0;
    // 只要读到内容
    while ((r = read(fd, buf, 32)) > 0)
    {
        // 循环对比读取到的字符,当发现'\n'时,就代表一行结束
        // 将换行之前的字符写入到终端进行输出
        // 如果读取到的字符串中没有换行,那么就把这次读取到的字符都写到终端上
        for (int i = 0; i < 32; i++)
        {
            if (buf[i] == '\n')
            {
                h++;
                if (h == n)
                {
                    write(1, buf, i);
                    printf("\n");
                    close(fd);
                    return 0;
                }
            }
        }
        write(1, buf, 32);
    }
    printf("\n");
    close(fd);
    return 0;
}

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值