C程序打印文件中的第一行和最后n行,我做错了什么?
C Program to print first and last n lines in a file, what am I doing wrong?
总的来说,我是编程新手。请注意,这是作业。
我正在使用 a-z 小写的 txt 文件。
我用命令./a.out test.txt
到运行程序,然后输入一个数字。
我的代码:
#include <stdio.h>
static void cat(FILE *fp, int num) {
int count = 0;
char buffer[4096];
while (fgets(buffer, sizeof(buffer), fp) != 0) {
if (count == num)
break;
else
count++;
fputs(buffer, stdout);
}
}
int main(int argc, char *argv[]) {
int num, count = 0;
long length;
char buffer[4096];
FILE *fp;
fp = fopen(argv[1], "r");
if (fp == NULL) {
printf("Can't open this file\n");
return 0;
}
scanf("%d", &num);
cat(fp, num);
printf("...\n");
fseek(fp, 0, SEEK_END);
length = ftell(fp);
fseek(fp, (length - 2), SEEK_SET);
printf("1\n");
while (fgets(buffer, sizeof(buffer), fp) != 0) {
fputs(buffer, stdout);
}
if (ftell(fp) == '\n') {
count++;
length = ftell(fp);
fseek(fp, (length - 4), SEEK_SET);
printf("2\n");
while (fgets(buffer, sizeof(buffer), fp) != 0) {
fputs(buffer, stdout);
}
} else { //<------ missing opening brace
length = ftell(fp);
fseek(fp, (length - 2), SEEK_SET);
printf("3\n");
while (fgets(buffer,s izeof(buffer), fp) != 0) {
fputs(buffer, stdout);
}
if (count == num) {
printf("4\n");
while (fgets(buffer, sizeof(buffer), fp) != 0) {
fputs(buffer, stdout);
}
}
fclose(fp);
return 0;
}
请帮忙!
1) 您应该检查文件大小是否小于缓冲区大小。
2) 如果您打算一次读取文件中的 n 行数据块,请一次读取一行。可能使用 fscanf。这样你就可以跟踪你有多少行 read/printed。这也有助于了解您的文件是否有足够的行数。
我重新格式化了您的代码以提高可读性。我指出的地方缺少 {
。正如发布的那样,代码无法编译。
您的程序应该能够打印前 n
行,但您的方法不适用于最后 n
行。
分配 n
个缓冲区数组:
char (*array)[4096] = calloc(4096, num);
对于读取的每一行,移动缓冲区并复制最后位置的行:
memmove(array[0], array[1], sizeof(array[0] * (num - 1));
strcpy(array[num - 1], buffer);
还有更有效的方法,但您应该能够实现这个简单的方法。
到达文件末尾时,打印数组中的非空行。
编辑:
这是一个完整的版本,它使用了一个 num+1
缓冲区数组。它读取整个文件,在读取时打印前 num
行,并始终将最后 num
行保留在数组中,循环读取下一行的位置 num+1
缓冲区。
在文件末尾,如果文件超过 num
行,则必须打印额外的行,如果在文件中间跳过行,则可能用 --------
分隔.打印最后 num
行或更少行:计算 pos
以找到正确的缓冲区模数 num+1
并且打印行直到最后。
代码如下:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int num, pos, count;
FILE *fp;
char (*array)[4096]; /* pointer to an array of buffers */
if (argc < 2) {
printf("Usage headtail filename [number]\n");
return 1;
}
fp = fopen(argv[1], "r");
if (fp == NULL) {
printf("Cannot open file %s\n", argv[1]);
return 1;
}
if (argc > 2) {
/* get the number from the command line if 2 args were given */
if (sscanf(argv[2], "%d", &num) != 1) {
num = -1;
}
} else {
/* otherwise read from standard input */
if (scanf("%d", &num) != 1) {
num = -1;
}
}
if (num < 0) {
printf("Invalid number\n"); /* negative or non numeric */
return 1;
}
/* allocate space for num+1 buffers */
array = malloc(4096 * (num + 1));
for (count = pos = 0; fgets(array[pos], 4096, fp) != NULL; count++) {
/* printing the first num lines */
if (count < num)
fputs(array[pos], stdout);
/* cycle buffers for num lines + 1 extra buffer */
if (++pos >= num + 1)
pos = 0;
}
if (count > num) {
/* more lines to print */
pos = count - num;
if (pos > num) {
/* print place holder for missing lines */
printf("...\n");
} else {
/* print from the last line printed */
pos = num;
}
for (; pos < count; pos++) {
fputs(array[pos % (num + 1)], stdout);
}
}
fclose(fp);
return 0;
}
总的来说,我是编程新手。请注意,这是作业。
我正在使用 a-z 小写的 txt 文件。
我用命令./a.out test.txt
到运行程序,然后输入一个数字。
我的代码:
#include <stdio.h>
static void cat(FILE *fp, int num) {
int count = 0;
char buffer[4096];
while (fgets(buffer, sizeof(buffer), fp) != 0) {
if (count == num)
break;
else
count++;
fputs(buffer, stdout);
}
}
int main(int argc, char *argv[]) {
int num, count = 0;
long length;
char buffer[4096];
FILE *fp;
fp = fopen(argv[1], "r");
if (fp == NULL) {
printf("Can't open this file\n");
return 0;
}
scanf("%d", &num);
cat(fp, num);
printf("...\n");
fseek(fp, 0, SEEK_END);
length = ftell(fp);
fseek(fp, (length - 2), SEEK_SET);
printf("1\n");
while (fgets(buffer, sizeof(buffer), fp) != 0) {
fputs(buffer, stdout);
}
if (ftell(fp) == '\n') {
count++;
length = ftell(fp);
fseek(fp, (length - 4), SEEK_SET);
printf("2\n");
while (fgets(buffer, sizeof(buffer), fp) != 0) {
fputs(buffer, stdout);
}
} else { //<------ missing opening brace
length = ftell(fp);
fseek(fp, (length - 2), SEEK_SET);
printf("3\n");
while (fgets(buffer,s izeof(buffer), fp) != 0) {
fputs(buffer, stdout);
}
if (count == num) {
printf("4\n");
while (fgets(buffer, sizeof(buffer), fp) != 0) {
fputs(buffer, stdout);
}
}
fclose(fp);
return 0;
}
请帮忙!
1) 您应该检查文件大小是否小于缓冲区大小。
2) 如果您打算一次读取文件中的 n 行数据块,请一次读取一行。可能使用 fscanf。这样你就可以跟踪你有多少行 read/printed。这也有助于了解您的文件是否有足够的行数。
我重新格式化了您的代码以提高可读性。我指出的地方缺少 {
。正如发布的那样,代码无法编译。
您的程序应该能够打印前 n
行,但您的方法不适用于最后 n
行。
分配 n
个缓冲区数组:
char (*array)[4096] = calloc(4096, num);
对于读取的每一行,移动缓冲区并复制最后位置的行:
memmove(array[0], array[1], sizeof(array[0] * (num - 1));
strcpy(array[num - 1], buffer);
还有更有效的方法,但您应该能够实现这个简单的方法。
到达文件末尾时,打印数组中的非空行。
编辑:
这是一个完整的版本,它使用了一个 num+1
缓冲区数组。它读取整个文件,在读取时打印前 num
行,并始终将最后 num
行保留在数组中,循环读取下一行的位置 num+1
缓冲区。
在文件末尾,如果文件超过 num
行,则必须打印额外的行,如果在文件中间跳过行,则可能用 --------
分隔.打印最后 num
行或更少行:计算 pos
以找到正确的缓冲区模数 num+1
并且打印行直到最后。
代码如下:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int num, pos, count;
FILE *fp;
char (*array)[4096]; /* pointer to an array of buffers */
if (argc < 2) {
printf("Usage headtail filename [number]\n");
return 1;
}
fp = fopen(argv[1], "r");
if (fp == NULL) {
printf("Cannot open file %s\n", argv[1]);
return 1;
}
if (argc > 2) {
/* get the number from the command line if 2 args were given */
if (sscanf(argv[2], "%d", &num) != 1) {
num = -1;
}
} else {
/* otherwise read from standard input */
if (scanf("%d", &num) != 1) {
num = -1;
}
}
if (num < 0) {
printf("Invalid number\n"); /* negative or non numeric */
return 1;
}
/* allocate space for num+1 buffers */
array = malloc(4096 * (num + 1));
for (count = pos = 0; fgets(array[pos], 4096, fp) != NULL; count++) {
/* printing the first num lines */
if (count < num)
fputs(array[pos], stdout);
/* cycle buffers for num lines + 1 extra buffer */
if (++pos >= num + 1)
pos = 0;
}
if (count > num) {
/* more lines to print */
pos = count - num;
if (pos > num) {
/* print place holder for missing lines */
printf("...\n");
} else {
/* print from the last line printed */
pos = num;
}
for (; pos < count; pos++) {
fputs(array[pos % (num + 1)], stdout);
}
}
fclose(fp);
return 0;
}