2016-02-14 53 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。通過這種方式,您可以跟蹤您讀取/打印的行數。這也有助於瞭解您的文件是否有足夠的行。

相關問題