2015-12-15 2 views
0

Мне нужно прочитать строку из stdin, а затем удалить все вхождения этой строки в файл. Я должен перезаписать исходный файл. Ниже я отправляю свой исходный код. Его проблемы в том, что я не знаю, какое условие остановки я должен добавить для цикла while, а также, как я могу перезаписать исходный файл? (Как вы можете видеть, я попытался добавить все слова, которые не равны данной строке в отдельный файл).C: Удалить все вхождения слова в файл

#include <stdio.h> 
#include <string.h> 

int main() 
{ 
    FILE *fp, *fp_out; 
    char s[50], del[50]; 

    fp = fopen("file_in", "r"); 
    fp_out = fopen("file_out", "a"); 

    fgets(del, 50, stdin); 
    fgets(s, 50, (FILE *)fp); 

    while(s != EOF) //I know that this does not work, what condition should I add? 
    { 
     fgets(s, 50, (FILE *)fp); 
     if(strcmp(s, del) != 0) 
      fprintf(fp_out, "%s ", s); 
    } 

    fclose(fp); 
    fclose(fp_out); 

    return 0; 
} 

Я уже говорил, что я также пытался добавить while(s != NULL), но это создает текстовый файл 592 МБ, содержащий все слова в моем текстовом файле ввода.

+1

вы не перезаписываете исходный файл, потому что вы его убьете, пока вы одновременно пытаетесь его прочитать. вы создаете новый временный файл, выполняете копирование/фильтрацию в этот временный файл. Затем вы удалите оригинал и переименуйте temp. –

+0

Что вы хотите для своего цикла: 'while (fgets (s, 50, fp))'. Чтобы понять, почему, посмотрите на [fgets return value] (http://www.cplusplus.com/reference/cstdio/fgets/). Также, прокатитесь на этом листе на 'fp'. Это уже ФАЙЛ *, поэтому нет причин бросать его. –

+0

Вы отбрасываете первую строку входного файла, то есть вы не обрабатываете ее перед чтением второй строки. –

ответ

1

Ваше состояние, а может быть:

while(fgets(s, sizeof s, fp)) { 

} 

fgets() возвращается NULL, когда он достигает конца файла или в случае ошибки. Также обратите внимание, что fgets() будет считывать новую строку в буфер, если есть пробел, который вы можете удалить перед сравнением строк. Обратите внимание, что литье до FILE* является излишним.

Чтобы удалить символ новой строки, если таковой имеется, вы можете использовать strchr():

char *p = strchr(del, '\n'); 
if(p) *p = '\0'; 

Однако

1) Вы сравниваете целую строку (прочитано fgets()) с словом вы читаете от stdin. Таким образом, эта замена не будет работать, если строка (строки) имеет более одного слова. Поэтому вам, вероятно, нужно разделить строку на слова, а затем использовать другой цикл для сравнения каждого слова в строке.

2) Вы не переписываете один и тот же файл. Таким образом, вы можете использовать rename() в конце всех замен, чтобы перезаписать исходный файл.

+0

Удаление исходного файла должно предшествовать переименованию. –

+0

Наконец-то я понял, что вы мне говорите: я должен использовать 'strtok' с разделителем' ''', чтобы сломать строку длиной не более 50 символов в словах, а затем сравнить каждое отдельное слово со строкой, которую я прочитал от stdin. Я прав? – Polb

+0

@CareyGregory Если есть проблема с разрешением, недопустимый путь и т. Д. 'Rename' удалит старый файл. –

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