c - Unix(在 C 中)尝试为 XV6 编写 tail

标签 c linux unix operating-system xv6

嗨 stackoverflow(读者)!

我正在使用 XV6 操作系统学习 Unix(找到文档 here )并且一直在尝试用 C 语言编写一个 tail 函数。预期输出为:

  1. tail是给出文件的最后10行
  2. tail - 给出文件的最后一行
  3. tail ...就是给最后10行文件...
  4. tail - ... 是给出...的最后几行
  5. 搜索 | tail是给出最后10个句子中包含

我写了两个版本的 tail,一个是使用 char* [] 实现的,另一个是写入文件然后从中读取(都在下面发布) 我使用 char* [] 实现尾部的版本似乎对实际命令更准确。但是,在我写入临时文件然后从中读取的版本中,我得到了更多行作为输出,我不确定为什么会这样。我的猜测是,在从一个文件读取并写入另一个文件时,'\n' 的位置变得一团糟。如果能帮助我解决问题,我将不胜感激!

如果我做了一些愚蠢的事情,请不要生我的气。我是 Unix 中 C 的新手,只是想学习。

tail.c 使用 char* []

#include "types.h"
#include "stat.h"
#include "user.h"
#include "fcntl.h"

char buf [512];

void tail (int fd, int toSub) {
  int n;
  int numLines = 0;
  int linesToPrint = 0;
  char *buffer;
  buffer = (char*) malloc (500000);
  int buffSize = 0;
  while ((n = read(fd, buf, sizeof(buf))) > 0) {
    for (int i = 0; i<n; i++) {
      buffer[buffSize] = (char)buf[i];
      buffSize++;
      if(buf[i] == '\n')
        numLines++;
    }
  }
  if (n < 0) {
    printf (1, "tail: read error \n");
    exit ();
  }
  if (numLines < toSub)
    linesToPrint = 0;
  linesToPrint = numLines - toSub;

  int counter = 0;
  for (int i = 0; i < buffSize; i++) {
    if (counter >= linesToPrint)
      printf(1,"%c",buffer[i]);
    if (buffer[i] == '\n')
      counter++;
  }
  free (buffer);
}

int main (int argc, char *argv[]) {
  int toSub = 10;
  int fd = -1;

  if (argc <= 1) {
    tail (0, toSub);
    exit();
  }
  else if (argc > 1 && argv[1][0] == '-') {
    char getToSub [10];
    for (int k=1; k<strlen(argv[1]); k++) {
      getToSub[k-1] = argv[1][k];
    }
    toSub = (atoi)(getToSub);
  }
  else {
    if((fd = open (argv[1], toSub)) < 0) {
      printf (1, "tail: cannot open %s\n", argv[1]);
      exit ();
    }
    tail (fd, toSub);
    close (fd);
  }
  if (argc > 2) {
    for (int i=2; i<argc; i++) {
      if((fd = open (argv[i], 0)) < 0) {
        printf (1, "tail: cannot open %s\n", argv[i]);
        exit ();
      }
      else {
        tail (fd, toSub);
        close (fd);
      }
    }
  }
  exit();
}

tail.c 使用写入

#include "types.h"
#include "stat.h"
#include "user.h"
#include "fcntl.h"

char buf [512];

void tail (int fd, int toSub) {
  int n;
  int numLines;
  int linesToPrint;
  int ptrDump;
  ptrDump = open ("tailDump", O_CREATE | O_RDWR);
  while ((n = read(fd, buf, sizeof(buf))) > 0) {
    write (ptrDump, buf, sizeof(buf));
    for (int i = 0; i<n; i++) {
      if(buf[i] == '\n')
        numLines++;
    }
  }
  if (n < 0) {
    printf (1, "tail: read error \n");
    exit ();
  }
  if (numLines < toSub)
    linesToPrint = 0;
  linesToPrint = numLines - toSub;

  close (ptrDump);
  ptrDump = open ("tailDump", 0);

  int counter = 0;
  while ((n = read(ptrDump, buf, sizeof(buf))) > 0) {
    for (int i = 0; i<n; i++) {
      if (counter > linesToPrint)
        printf(1,"%c",buf[i]);
      if (buf[i] == '\n')
        counter++;
      }
    }
    close (ptrDump);
    unlink("tailDump");
}

int main (int argc, char *argv[]) {
  int toSub = 10;
  int fd = -1;

  if (argc <= 1) {
    tail (0, toSub);
    exit();
  }
  else if (argc > 1 && argv[1][0] == '-') {
    char getToSub [10];
    for (int k=1; k<strlen(argv[1]); k++) {
      getToSub[k-1] = argv[1][k];
    }
    toSub = (atoi)(getToSub);
  }
  else {
    if((fd = open (argv[1], toSub)) < 0) {
      printf (1, "tail: cannot open %s\n", argv[1]);
      exit ();
    }
    tail (fd, toSub);
    close (fd);
  }
  if (argc > 2) {
    for (int i=2; i<argc; i++) {
      if((fd = open (argv[i], 0)) < 0) {
        printf (1, "tail: cannot open %s\n", argv[i]);
        exit ();
      }
      else {
        tail (fd, toSub);
        close (fd);
      }
    }
  }
  exit();
}

我将代码放在我的 Github 上(找到 here )以及 tail_using_str.c 和 tail_using_file.c

最佳答案

我认为你的问题出在这里:

  while ((n = read(fd, buf, sizeof(buf))) > 0) {
    write (ptrDump, buf, sizeof(buf));

您读取 n 字节,但当您写入时,您写入 sizeof(buf) 字节。换句话说,您可能写入了太多字节。

也许你想要这个:

  while ((n = read(fd, buf, sizeof(buf))) > 0) {
    write (ptrDump, buf, n);
                         ^
                        note

关于c - Unix(在 C 中)尝试为 XV6 编写 tail,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42061824/

相关文章:

c - 为什么这个 int 不占用我数组的两个字节?

python - 为什么 current_url 在 Ubuntu 16.04 上引发 "No JSON object could be decoded"w/Selenium & PhantomJS?

linux - BASH getopts 可选参数

linux - Crontab 作业未针对具体值运行;但执行相对时间值

在 C 中创建您自己的控制台图形库

C 程序未完成所有步骤

javascript - 我如何从 linux 的 stdout 读取数据到 ajax 并获得某个字符串?

linux - sudo dpkg -i mod-pagespeed-*.deb 给出 "not a debian format archive"错误

json - 使用jq合并json文件,获取文件列表长度太长报错

linux - 计算多行中某个字段的出现次数