ibilalkayy Ответов: 2

Как скопировать все строки из файла, кроме удаленной?


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

int main(){
  FILE *fp1, *fp2;
  char fname[50] = "fiile.csv", ch, toFind[50], str[200], saved[200];
  int delLine=1, count=1;
  fp1 = fopen(fname, "r");
  fp2 = fopen("new.csv", "w");
  char * line1 = NULL;

  printf("Enter your id card number: ");
  scanf("%s", toFind);

  while(fgets(str, 200, fp1)){
    line1 = strtok(str, "\n");
    strcpy(saved, line1);
    if(strstr(saved, toFind)){
      printf("%s\n", saved);
      exit(0);
    }
  }

  return 0;
}


Что я уже пробовал:

В этом коде я пытаюсь удалить строку, которую я получу через номер идентификационной карты. Я смог извлечь эту строку, но не смог удалить ее. Я знаю, что необходим временный файл, и, скопировав весь текст, кроме удаленного, я могу это сделать. Но проблема в том, что я не могу скопировать все строки, кроме удаленной, как в этом примере
Пример
ch = getc(fp1);
//except the line to be deleted
if (temp != delete_line){
    putc(ch, fp2);
}

Здесь используется getc (), но я использую fgets() только для того, чтобы найти конкретную строку через номер идентификационной карты. Я не знаю, возможно ли это через getc() или есть какой-то другой способ?

2 Ответов

Рейтинг:
2

Rick York

Попробуйте этот код. Он ищет точное совпадение номера карты и записывает данные в новый файл, если они не совпадают. Размеры буфера добавили 1, чтобы обеспечить завершающий нуль, и поэтому вам не нужно вычитать его везде, где вы используете буфер.

#define BUFFER_LENGTH 199

int main()
{
  FILE *fp1, *fp2;
  char fname[50] = "fiile.csv", ch, toFind[50], str[BUFFER_LENGTH+1], saved[BUFFER_LENGTH+1];
  int count=0;
  fp1 = fopen(fname, "r");
  fp2 = fopen("new.csv", "w");
  char * line1 = NULL;

  printf("Enter your id card number: ");
  scanf("%s", toFind);

  while( fgets( str, BUFFER_LENGTH, fp1 ) )
  {
    ++count;
    strcpy( saved, str );     // save a copy because strtok is destructive
    line1 = strtok( str, "," );
    if( strcmp( line1, toFind ) == 0 )  // first token must match number exactly
    {
        printf( "line %d : %s\n", count, saved );   // found it, print it
//      exit(0);   // why?  have to write the rest of the file
    }
    else
    {
        fputs( saved, fp2 );   // not the one - write it to new file
    }
  }

  // close the files

  fclose( fp2 );
  fclose( fp1 );
  return 0;
}


Рейтинг:
0

Dave Kreskowiak

CSV-файлы-это просто текстовый файл. В них нет ничего особенного.

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

Извините за грубость моего кодекса. Прошло уже больше десяти лет с тех пор, как я касался C/C++:

int main(){
  FILE *sourceFP, *destinationFP;
  char fname[50] = "file.csv";
  char idToFind[50];

  //char * line1 = NULL;
  char lineBuffer[4096];                    // 4K text buffer for storing a line

  sourceFP = fopen(fname, "r");
  destinationFP = fopen("new.csv", "w");


  printf("Enter your id card number: ");
  scanf("%s", idToFind);

  while( fgets(lineBuffer, 4096, sourceFP ) != NULL )
  {
    lineBuffer = strtok(lineBuffer, ",");         // Your delimiter character should NOT be "\n"
                                                  // COMMA Separated Values
    // strcpy(saved, line1);                      // Why? You don't need to copy the line!
    if( strstr(idToFind, lineBuffer) == NULL)
    {
      // The id was not found so write the line to the new file.
      printf("%s\n", lineBuffer);
      // exit(0);                                 // WHAT?! Write one line to the file then quit the app?
    }
  }

  return 0;
}


Richard MacCutchan

Использование strtok(lineBuffer, "\n") является правильным, поскольку он удаляет символ новой строки. Но использование запятой означает, что данные, которые вы записываете в новый файл, будут состоять только из первого поля каждой строки.

Dave Kreskowiak

Ах, это правда. Как я уже сказал, мой C/C++ действительно ржавый.