2016-02-14 28 views
1

我是一般的编程新手。请注意,这是作业。 我正在使用a-z小写的txt文件。 我使用命令./a.out test.txt来运行程序,然后输入一个数字。C程序打印一个文件中的第一个和最后一个n行,我做错了什么?

我的代码:

#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; 
} 

请帮助!

+0

请加上运营商之间的空白你的代码是难以阅读,这是什么'FTELL(FP)=='\ n''?你为什么这样做? –

+0

你发布的代码没有编译? –

回答

1

我重新格式化了您的代码以提高可读性。在我指出的地方有一个缺失的{。发布后,代码不能编译。

您的程序应该能够打印第一行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行或更少的行:计算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; 
} 
+0

你是什么意思?正如我上面所说的,我对编程并不是很了解,所以你能解释一下吗? –

+0

感谢您的回答!现在我只需要了解它...... P –

+0

@ N.Cvt .:我用更简单,更有效的方法更新了答案,该方法使用更少的内存。研究这一个,它应该更容易理解。 – chqrlie

0

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

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

相关问题