2013-12-21 80 views

回答

3

試試這個:

/* C Program Delete a specific Line from a Text File 
*/ 
#include <stdio.h> 

int main() 
{ 
    FILE *fileptr1, *fileptr2; 
    char filename[40]; 
    char ch; 
    int delete_line, temp = 1; 

    printf("Enter file name: "); 
    scanf("%s", filename); 
    //open file in read mode 
    fileptr1 = fopen(filename, "r"); 
    ch = getc(fileptr1); 
    while (ch != EOF) 
    { 
     printf("%c", ch); 
     ch = getc(fileptr1); 
    } 
    //rewind 
    rewind(fileptr1); 
    printf(" \n Enter line number of the line to be deleted:"); 
    scanf("%d", &delete_line); 
    //open new file in write mode 
    fileptr2 = fopen("replica.c", "w"); 
    ch = 'A'; 
    while (ch != EOF) 
    { 
     ch = getc(fileptr1); 
     //except the line to be deleted 
     if (temp != delete_line) 
     { 
      //copy all lines in file replica.c 
      putc(ch, fileptr2); 
     } 
     if (ch == '\n') 
     { 
      temp++; 
     } 
    } 
    fclose(fileptr1); 
    fclose(fileptr2); 
    remove(filename); 
    //rename the file replica.c to original name 
    rename("replica.c", filename); 
    printf("\n The contents of file after being modified are as follows:\n"); 
    fileptr1 = fopen(filename, "r"); 
    ch = getc(fileptr1); 
    while (ch != EOF) 
    { 
     printf("%c", ch); 
     ch = getc(fileptr1); 
    } 
    fclose(fileptr1); 
    return 0; 
} 

參考 - http://www.sanfoundry.com/c-program-delete-line-text-file/

2

有幾種方法可以刪除一行, 一個簡單的方法是打開兩個文件,一入一出。

然後逐行復制並在完成後跳過要刪除的行 刪除舊文件並將新文件重命名爲舊名稱。

fopen() 
fgets() 
fputs() 
rename() 
unlink() 

編輯:上述解決方案將很好地工作一個小文件,但通過註釋它不適合大量文件,所以在這裏談到的替代解決方案(GCC C99),其內容在整個文件中,找到了名稱然後在緩衝區中將該行向前移動。

#include <stdio.h> 
#include <sys/stat.h> 
#include <stdlib.h> 
#include <stdbool.h> 

static size_t deleteLine(char*, size_t, const char*); 

int main(int argc, char* argv[]) 
{ 
    char file[] = "yourfile.txt"; 

    if (--argc) 
    { 
    struct stat st; 
    if (stat(file, &st) != -1) 
    { 
     // open the file in binary format 
     FILE* fp = fopen(file, "rb"); 
     if (fp != NULL) 
     { 
     // allocate memory to hold file 
     char* buffer = malloc(st.st_size); 

     // read the file into a buffer 
     if (fread(buffer, 1, st.st_size, fp) == st.st_size) 
     { 
      fclose(fp); 

      size_t newSize = deleteLine(buffer, st.st_size, argv[1]); 

      fp = fopen(file, "wb"); 
      if (fp != NULL) 
      { 
      fwrite(buffer, 1, newSize, fp); 
      fclose(fp); 
      } 
      else 
      { 
      perror(file); 
      } 
     } 
     free(buffer); 
     } 
     else 
     { 
     perror(file); 
     } 
    } 
    else 
    { 
     printf("did not find %s", file); 
    } 
    } 
    return 0; 
} 

static size_t deleteLine(char* buffer, size_t size, const char* playerName) 
{ 
    // file format assumed to be as specified in the question i.e. name{space}somevalue{space}someothervalue\n 
    // find playerName 
    char* p = buffer; 
    bool done = false; 
    size_t len = strlen(playerName); 
    size_t newSize = 0; 
    do 
    { 
    char* q = strchr(p, *playerName); // look for first letter in playerName 
    if (q != NULL) 
    { 
     if (strncmp(q, playerName, len) == 0) // found name? 
     { 
     size_t lineSize = 1; // include \n already in line size 

     // count number of characters the line has. 
     for (char* line = q; *line != '\n'; ++line) 
     { 
      ++lineSize; 
     } 

     // calculate length left after line by subtracting offsets 
     size_t restSize = (size_t)((buffer + size) - (q + lineSize)); 

     // move block with next line forward 
     memmove(q, q + lineSize, restSize); 

     // calculate new size 
     newSize = size - lineSize; 
     done = true; 
     } 
     else 
     { 
     p = q + 1; // continue search 
     } 
    } 
    else 
    { 
     puts("no such name"); 
     done = true; 
    } 
    } 
    while (!done); 

    return newSize; 
} 
+1

如果我想這樣做對幾千行的幾個文件?這不是一個很好的解決方案...... – Nepho

+0

這是正確的,我的答案是在OPs問題之後校準的,也就是某種學校任務的文件長度大約爲10行,在現實世界中會有不同的做法。 –

+0

你不需要'main'中的'free(buffer)'嗎? –

相關問題