Pelles C forum
C language => Beginner questions => Topic started 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 ?
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);
}
-
using that append mode is reason for that problem.
-
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
-
A string function strstr() may help.
If you want to delete string, use a temporary file and copy relevant parts to it.
-
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 ?
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
-
a silly example
#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;
}
test_str_del.txt
test foo in foo
foo1
end
EDIT: fixed version with some comments
-
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.
#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;
}
-
1. fgets read a LF to buffer, so remove it
2. use binary format to avoid translations
3. write remainder buffer if needed
-
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
#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;
}
-
use debugger to learn how code works.
int keylen = strlen(val); // keyword length with LF
val[--keylen] = 0; // remove LF and fix keylen
-
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 :
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';
}
}
-
Some parts of the file could be locked.
-
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 :
#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