Pelles C forum

C language => Beginner questions => Topic started by: John1 on September 21, 2019, 06:16:36 PM

Title: How to delete some Content in a File ?
Post by: John1 on September 21, 2019, 06:16:36 PM
Hello,

I was trying to delete some Strings from a File.

The Function below gets a String, which must be overwritten.
Nothing happens after the execution of the Function, it goes back to the Menu, and after showing the List there is still the same String in the content of the File. Seems the Function delete won't work.

What could be changed ?

Code: [Select]
void deleteElement(char* ow) {
 char* overWrite = "                                     ";
 FILE *fp;
 fpos_t position;

 fp = fopen(DATAFILE,"a+b");
 fgetpos(fp, &position);
 fputs(ow, fp);
 
 fsetpos(fp, &position);
 fputs(overWrite, fp);
 fclose(fp);
}
Title: Re: How to delete some Content in a File ?
Post by: TimoVJL on September 22, 2019, 12:42:09 PM
using that append mode is reason for that problem.
Title: Re: How to delete some Content in a File ?
Post by: John1 on September 22, 2019, 03:19:26 PM
Hello TimoVJL,

Thanks, yes it was not correct with (a+b).

Instead now I use (r+), which seems the only option.

But now when I will delete something it deletes just one time the first String it can find, the other Strings remain, also after executing the delete function. Normaly it must find the String through "fgetpos(fp, &position);".

Kind regards
John1
Title: Re: How to delete some Content in a File ?
Post by: TimoVJL on September 22, 2019, 04:10:46 PM
A string function strstr() may help.
If you want to delete string, use a temporary file and copy relevant parts to it.
Title: Re: How to delete some Content in a File ?
Post by: John1 on September 25, 2019, 08:02:53 PM
Hello TimoVJL,

Thank you for your Answers.

I tried to change the code as your advices. But somehow it doesn't delete exactly the content.
Now it deletes all String, except the last String in the List.

In the Web I found some examples, but not clear how to use it.

Maybe you might give some hints with some code ?

Code: [Select]
void deleteElement(char* ow) {
 FILE *fp;

 fp = fopen(DATAFILE,"r");
 while(fread(&carV, sizeof(carV), 1, fp) == 1) {
  printf("\nOld-Content: %s\n", carV);       //Debug
  printf("\nKey value to delete: %s\n", ow); //Debug
  if(strstr(carV, ow) != 0) {
   printf("\nString: %s\n", carV);           //Doesn't print out ?
  }             
 }
 fclose(fp);
 printf("\nNew-Content: %s\n", carV);        //Debug
 remove(DATAFILE);

 fp = fopen(DATAFILE ,"a");
 if(fwrite(&carV, sizeof(carV), 1, fp) != 1) {
  fprintf(stderr, "Error in write, in %s\n", DATAFILE);
  fclose(fp);
  return;
 }   
 fclose(fp);
}

Kind regards
John1
Title: Re: How to delete some Content in a File ?
Post by: TimoVJL on September 25, 2019, 09:12:14 PM
a silly example
Code: [Select]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int __cdecl main(void)
{
char *file = "test_str_del.txt";
FILE *fp = fopen(file, "rb"); // binary format
char *s = "foo";
int keylen = strlen(s);
if (fp) {
fseek(fp, 0, SEEK_END);
int len = ftell(fp);
fseek(fp, 0, SEEK_SET);
char *pbuf = malloc(len+1);
//*(pbuf + 1) = 0; //
if (pbuf) {
fread(pbuf, len, 1, fp); // read text to buffer
fclose(fp);
fp = NULL;
char *p1 = pbuf, *p = pbuf;
while (p = strstr(p, s)) { // find next search keyword
if (!fp) fp = fopen(file, "wb"); // rewrite file
fwrite(p1, p - p1, 1, fp); // write block before keyword
p += keylen; // past deleted keyword
p1 = p; // savepoint after keyword
}
if (p1) // write rest of text
fwrite(p1, (pbuf + len) - p1, 1, fp);
}
fclose(fp);
}
return 0;
}
Code: [Select]
test_str_del.txt
test foo in foo
foo1
end
EDIT: fixed version with some comments
Title: Re: How to delete some Content in a File ?
Post by: John1 on September 26, 2019, 10:57:15 PM
Hello TimoVJL,

Thanks a lot for your hint. it's deleting well.
Might be simple for you, but I have some problems to understand it.
I'm sorry I usually used Java as beginner with a lot of API prepared Methods(Functions), which seemed to be simpler.
That I'm using C for this it's just to test and learn as very new beginner, hopefully I can learn something.

Somehow I understand your code, but maybe you may post some //explains in it, seems in part to calculate something with keylen in the while loop ?

Perhaps I may ask you why the Code below, with little modification, doesn't work ?
It doesn't execute the while loop.

Thank you for your patience.

Code: [Select]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define file "test_str_del.txt"

int main(void) {
  FILE *fp;
  char val[256];  // new add, instead "s" now it is "val"
  if(fgets(val,sizeof(val),stdin) == NULL) { // new add
   printf("Wrong Input\n");     
  } 

   fp = fopen(file, "r");
   int keylen = strlen(val);
   if (fp) {
    fseek(fp, 0, SEEK_END);
    int len = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    char *pbuf = malloc(len);
    if (pbuf) {
     fread(pbuf, len, 1, fp);
     fclose(fp);
     fp = NULL;
     char *p1 = pbuf, *p = pbuf;
     while (p = strstr(p, val)) {
       if (!fp) fp = fopen(file, "w");
       fwrite(p1, p - p1, 1, fp);
       p += keylen;
       printf("keylen :  %d\n" , keylen); // ?
       p1 = p;
     }
   }
   fclose(fp);
  }
 return 0;
}
Title: Re: How to delete some Content in a File ?
Post by: TimoVJL on September 27, 2019, 12:22:03 AM
1. fgets read a LF to buffer, so remove it
2. use binary format to avoid translations
3. write remainder buffer if needed
Title: Re: How to delete some Content in a File ?
Post by: John1 on September 28, 2019, 09:03:05 PM
Hello TimoVJL,

Thanks for the explanation, now I can understand it a bit better.

Sorry for annoying you, but I added your corrections, and now it can't execute.
I think because of the last fwrite(p1, (pbuf + len) - p1, 1, fp);  , throws an exception, as I could more or less find out with debugging.

CRT: unhandled exception (main) -- terminating
*** Process returned 255 ***


Kind regards
John1

Code: [Select]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define file "test_str_del.txt"

int main(void) {
  FILE *fp;
  char val[256];
  val[strcspn(val, "\r\n")] = 0;  // does remove the carriage return and newline ?
  if(fgets(val,sizeof(val),stdin) == NULL) {
   printf("Wrong Input\n");     
  } 
  fp = fopen(file, "rb");
  int keylen = strlen(val);

  if (fp) {
   fseek(fp, 0, SEEK_END);
   int len = ftell(fp);
   fseek(fp, 0, SEEK_SET);
   char *pbuf = malloc(len+1);

   if (pbuf) {
    fread(pbuf, len, 1, fp);
    fclose(fp);
    fp = NULL;
    char *p1 = pbuf, *p = pbuf;

    while (p = strstr(p, val)) {
     if (!fp){ fp = fopen(file, "wb");}
      fwrite(p1, p - p1, 1, fp);
      p += keylen;
      p1 = p;
     }
     if (p1) { // write rest of text
      fwrite(p1, (pbuf + len) - p1, 1, fp); // doesn't execute
      printf("file almost finished");
     }
    }
    fclose(fp);
   }
  return 0;
}

Title: Re: How to delete some Content in a File ?
Post by: TimoVJL on September 29, 2019, 02:59:48 PM
use debugger to learn how code works.
Code: [Select]
  int keylen = strlen(val); // keyword length with LF
  val[--keylen] = 0; // remove LF and fix keylen
Title: Re: How to delete some Content in a File ?
Post by: John1 on September 29, 2019, 08:18:31 PM
Hello TimoVJL,

Thanks a lot, it works now. It compile and execute well, just I have a problem that it do not delete as expected. Something is messed up, maybe from the adding function. I will play with it around, and perhaps open another post.

And thank you, I will try to learn, how to debug through Pelles C, or maybe also using some other Debugger (e.g. GDB or WinDbg) .

Kind Regards
John1

p.s my adding function :

Code: [Select]
void addNewElement(void) {
 printf("Data :  ");
 if(fgets(carV, BUF, stdin) == NULL) {
  fprintf(stderr, "Wrong Input\n");
  return;
 }
 killNL(carV);

 FILE *fp = fopen(DATAFILE, "ab");

 if(fp == NULL) {
  printf("Error in open: %s\n", DATAFILE);
  exit(EXIT_FAILURE);
 }
 if(fwrite(&carV, sizeof(carV), 1, fp) != 1) {
  fprintf(stderr, "Error in write, in %s\n", DATAFILE);
  fclose(fp);
  return;
 }
 fclose(fp);
}

//killNL
void killNL(char *str) {
 size_t p = strlen(str);
 if(str[p-1] == '\n') {
  str[p-1] = '\0';
 }
}

Title: Re: How to delete some Content in a File ?
Post by: Grincheux on October 16, 2019, 06:32:50 PM
Some parts of the file could be locked.
Title: Re: How to delete some Content in a File ?
Post by: John1 on October 18, 2019, 12:50:22 PM
Hello Grincheux,

What do you mean, with, some parts might be locked ?

The Strings in the File are not listed straight.

Sting one
  String two
  String three


But instead somewhere randomly.

String one
                                                      String two
                                                                                               String three


Perhaps this prevents the funciton to find and delete the Strings as well ?

In this Code it is deleted well, but not ever :

Code: [Select]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define file "test_str_del.txt"

char carV[256];

void deleteElement() {
 FILE *fp;
    char value[256];
value[strcspn(value, "\r\n")] = 0;  // new add, instead "s" now it is "val"
printf("Data to delete :  ");
    if(fgets(value,sizeof(value),stdin) == NULL) { // new add
     printf("Wrong Input\n");     
            } 


fp = fopen(file, "rb");
int keylen = strlen(value);
value[--keylen] = 0; // remove CR and fix keylen
if (fp) {
fseek(fp, 0, SEEK_END);
int len = ftell(fp);
fseek(fp, 0, SEEK_SET);
char *pbuf = malloc(len+1);
if (pbuf) {
fread(pbuf, len, 1, fp);
fclose(fp);
fp = NULL;
            char *p1 = pbuf, *p = pbuf;
while (p = strstr(p, value)) {
if (!fp){ fp = fopen(file, "wb");}
fwrite(p1, p - p1, 1, fp);
p += keylen;
p1 = p;
}
            if (p1) { // write rest of text
     fwrite(p1, (pbuf + len) - p1, 1, fp); // doesn't execute
//printf("file almost finished");
    }
}
fclose(fp);
    }
}


void killNL(char *str) {
 size_t p = strlen(str);
 if(str[p-1] == '\n') {
  str[p-1] = '\0';
 }
}

void addNewElement(void) {
 printf("Data to input :  ");
 if(fgets(carV, 256, stdin) == NULL) {
  fprintf(stderr, "Wrong Input\n");
  return;
 }
 killNL(carV);

 FILE *fp = fopen(file, "ab");

 if(fp == NULL) {
  printf("Error in open: %s\n", file);
  exit(EXIT_FAILURE);
 }
 if(fwrite(&carV, sizeof(carV), 1, fp) != 1) {
  fprintf(stderr, "Error in write, in %s\n", file);
  fclose(fp);
  return;
 }
 fclose(fp);
}

int main(void) {
addNewElement();
addNewElement();
    deleteElement();
return 0;
}

Thanks