2013-12-21 2 views
2

Пример:Как удалить определенную строку из текстового файла в C?

George 50 40
Lime 30 20
Karen 10 60

do { 
    printf("\nInput player name:[1..10] "); 
    fgets(name,10,stdin); 
} 

Введите имя: Известь

Затем текстовый файл будет:

George 50 40
Karen 10 60

+0

Я сомневаюсь, что о коде, является ли C ...: -/ – rjv

+0

** Подсказка: ** если() –

ответ

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() 

EDIT: выше решение будет работать нормально с небольшим файлом, но, как замечанием он не подходит для большого файла, так что здесь приходит альтернативное решение (GCC C99), который считывает весь файл, находит name затем перемещает строки после этой строки вперед в буфере.

#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

, это правильно, мой ответ был откалиброван после вопроса OP, то есть какая-то школьная задача с файлом длиной около 10 строк, в реальной проблеме можно было бы по-другому. –

+0

вам не нужно «free (buffer)» в 'main'? –

Смежные вопросы