2013-10-18 67 views
0

我想複製一個文件,跳過其前n行,最後m行使用open,read,write和lseek (例如n = 1,m = 2,源文件:
AAAAAAA
BBBBBBB
CCCCCCC
DDDDDDD複製文件跳過前n行和後m行

DEST文件:
BBBBBBB)

我知道如何複製文件,但不知道如何跳過線。這裏是我的副本代碼:

char buf[128]; 
    size_t size; 

    int source = open(argv[1], O_RDONLY); 
    int dest = open(argv[2], O_CREAT | O_APPEND | O_WRONLY); 

    if(source == -1) { 
      printf("error"); 
      return; 
    } 
    if(dest == -1) { 
      printf("error"); 
      return; 
    } 

    while((size = read(source, buf, sizeof(buf))) > 0) { 
      write(dest, buf, size); 
    } 

    close(source); 
    close(dest); 

我怎樣才能解決這個問題?

+0

如何跳過第N行是顯而易見的,不是嗎?只要繼續閱讀,直到你通過N個換行符。 – Barmar

+0

你爲什麼在輸出文件上使用'O_APPEND'?你真的想追加到目標文件的末尾,而不是覆蓋它嗎? – Barmar

+0

是的,我不應該使用O_APPEND我的壞 – keysersoze

回答

2

您應該使用fgets來讀取您的文件,因爲它會逐行讀取它。

因爲它是不平凡說你有多少行總共有我會建議你

  • 使用fgets到逐行讀取文件中的行
  • 跳過輸出第一n
  • 寫剩下的放到你的輸出文件中並計算行數並記住每行的長度。
  • 使用ftruncate截斷最後的m行。

這應該做的伎倆:

void copy_nm(char * source, char * dest, int n, int m) { 
    FILE * in = fopen(source, "r"); 
    FILE * out = fopen(dest, "w"); 

    size_t file_length = 0; 
    size_t line_lengths[m + 1]; 
    memset(line_lengths, 0 , sizeof(line_lengths)); 

    int lengths_iterator = 0; 


    char buffer[0x400]; 

    while (fgets(buffer, sizeof(buffer), in)) { 
     size_t length = strlen(buffer); 

     if (n) { // skip this line 
      if (buffer[length - 1] == '\n') // only if it is a real line 
       n--; 
      continue; 
     } 

     fwrite(buffer, length, 1, out); 
     line_lengths[lengths_iterator] += length; 
     file_length += length; 

     if (buffer[length - 1] != '\n') { // line was longer then the buffer 
      continue; 
     } 

     lengths_iterator++; 
     lengths_iterator %= m+1; 

     line_lengths[lengths_iterator] = 0; 
    } 

    for (lengths_iterator = 0; lengths_iterator < m+1; lengths_iterator++) { 
     file_length -= line_lengths[lengths_iterator]; 
    } 

    fseek(out, 0, SEEK_SET); // rewind before truncating 
    ftruncate(fileno(out), file_length); 

} 
+0

唯一棘手的問題是處理比你的'fgets'緩衝區更長的行。 – Barmar

+0

您不需要記住所有行的長度,只需記住最後一行M行。完成後,從文件大小中減去這些總數,然後截斷爲該長度。 – Barmar

+0

@Barmar線越長,你的緩衝區最後就不會有'\ n',只要檢查一下,你就很好。 –