嗨 stackoverflow(读者)!
我正在使用 XV6 操作系统学习 Unix(找到文档 here )并且一直在尝试用 C 语言编写一个 tail 函数。预期输出为:
- tail是给出文件的最后10行
- tail - 给出文件的最后一行
- tail ...就是给最后10行文件...
- tail - ... 是给出...的最后几行
- 搜索 | 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/