繁体   English   中英

C程序在文件中打印第一行和最后n行,我在做什么错?

[英]C Program to print first and last n lines in a file, what am I doing wrong?

我是编程新手。 请注意,这是用于家庭作业。 我正在使用带有小写字母az的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;
}

请帮忙!

我重新格式化了您的代码以提高可读性。 缺少{我指示的地方。 如前所述,该代码无法编译。

您的程序应该能够打印前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;
}

1)您应该检查文件大小是否小于缓冲区大小。

2)如果您打算一次读取文件中的n行数据,请一次读取一行。 可能使用fscanf。 这样,您可以跟踪已读/打印的行数。 这也有助于了解您的文件是否有足够的行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM