0

how can i delete characters occurrences from a file in C

The program has to search in the file and then delete for example all "a" or all "b"

I found a program that removes words, but i don't know how to turn it to remove only characters

/**
* C program to delete a word from file.
*/

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

#define BUFFER_SIZE 1000


 void removeAll(char * str, const char * toRemove);

 int main()
{
FILE * fPtr;
FILE * fTemp;
char path[100];
 
char toRemove[100];
char buffer[1000];

/* Input source file path path */
printf("Enter path of source file: ");
scanf("%s", path);

printf("Enter word to remove: ");
scanf("%s", toRemove);


/*  Open files */
fPtr  = fopen(path, "r");
fTemp = fopen("delete.tmp", "w"); 

/* fopen() return NULL if unable to open file in given mode. */
if (fPtr == NULL || fTemp == NULL)
{
    /* Unable to open file hence exit */
    printf("\nUnable to open file.\n");
    printf("Please check whether file exists and you have read/write privilege.\n");
    exit(EXIT_SUCCESS);
}

/*
 * Read line from source file and write to destination 
 * file after removing given word.
 */
while ((fgets(buffer, BUFFER_SIZE, fPtr)) != NULL)
{
    // Remove all occurrence of word from current line
    removeAll(buffer, toRemove);

    // Write to temp file
    fputs(buffer, fTemp);
}


/* Close all files to release resource */
fclose(fPtr);
fclose(fTemp);


/* Delete original source file */
remove(path);

/* Rename temp file as original file */
rename("delete.tmp", path);

printf("\nAll occurrence of '%s' removed successfully.", toRemove);

return 0;
}


/**
* Remove all occurrences of a given word in string.
*/
void removeAll(char * str, const char * toRemove)
{
int i, j, stringLen, toRemoveLen;
int found;

stringLen   = strlen(str);      // Length of string
toRemoveLen = strlen(toRemove); // Length of word to remove


for(i=0; i <= stringLen - toRemoveLen; i++)
{
    /* Match word with string */
    found = 1;
    for(j=0; j < toRemoveLen; j++)
    {
        if(str[i + j] != toRemove[j])
        {
            found = 0;
            break;
        }
    }

    /* If it is not a word */
    if(str[i + j] != ' ' && str[i + j] != '\t' && str[i + j] != '\n' && str[i + j] != '\0') 
    {
        found = 0;
    }

    /*
     * If word is found then shift all characters to left
     * and decrement the string length
     */
    if(found == 1)
    {
        for(j=i; j <= stringLen - toRemoveLen; j++)
        {
            str[j] = str[j + toRemoveLen];
        }

        stringLen = stringLen - toRemoveLen;

        // We will match next occurrence of word from current index.
        i--;
    }
  }
}

And another one that i wrote :

#include<stdio.h>
#include<stdlib.h>
int SuppAppCara(char c, char nomfichier[50] ){
int i,j;
for (i=0; i<nomfichier ;i++)
{
if ( nomfichier[i]==c){
i--;
}
}
int main() {
FILE*f;
printf(" Saisir le nom du fichier:");
gets(nomfichier);
f=fopen(nomfichier,"r");
if (f==NULL){
printf("erreur d'ouverture");
exit(1);
}
FILE*f2;
f2=fopen("inter.txt","w");
printf(" entrer le caractére a supprimé : ");
scanf("%c",&c);
while( c=fgetc(f)!=EOF){
if (SuppAppCara(c,nomfichier[50]) == c){
fprintf(f2,"%s",nomfichier);
}
}
printf(" le caractere %c est supprimer avec succes ",c);
fclose(f2);
fclose (f);
remove(nomfichier);
rename("inter.txt",nomfichier);
}
}

The second program gives the following errors : enter image description here

Please can you help me? Either with the first or second, i am not that strong in C language and i been working on it for few days

Thanks

  • 3
    Never use `"%s"` in scanf. You must use a maximum field width on an `s` conversion specifier, or you might as well just use `gets`. And don't use `gets` – William Pursell Jan 04 '21 at 15:18
  • 2
    `Unable to open file` is the canonical example of a useless error message. You must include the path, the reason for the failure, and the message should be written to stderr. Use: `if( (fPtr = fopen(path, "r")) == NULL ){ perror(path); ...` – William Pursell Jan 04 '21 at 15:20
  • 1
    @WilliamPursell thanks for answer, should i use fgets ? – Ahmed Montasser Rossafi Jan 04 '21 at 15:20
  • 3
    Note that `while( c=fgetc(f)!=EOF){` means `while (c = (fgetc(f) != EOF)){` and not what you need: `while ((c = fgetc(f)) != EOF){`. Note, too, that the variable that accepts the value from `fgetc()` needs to be an `int`, not a `char`. It isn't clear where you declare `c` — it a parameter to the function, but the loop is in `main()`. – Jonathan Leffler Jan 04 '21 at 15:22
  • @AhmedMontasserRossafi - Yes `fgetc()` (or `fgets()`) is a better choice, There is much written about the negatives of using `gets()`. – ryyker Jan 04 '21 at 15:24
  • 1
    Note too that [The `gets()` function is far too dangerous to be used — ever!](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-dangerous-why-should-it-not-be-used) – Jonathan Leffler Jan 04 '21 at 15:27
  • 1
    Please read up about how to create an MCVE ([Minimal, Complete, Verifiable Example](https://stackoverflow.com/help/mcve) — or MRE or whatever name SO now uses) or an SSCCE ([Short, Self-Contained, Correct Example](http://sscce.org/)). The second program shown does not compile. It's missing a close brace at the end of the function (but has an extraneous one after `main()`), amongst other problems. The call to it is erroneous. There is no variable `c` defined in `main()`, nor is `nomfichier` defined in `main()`. You're using `c` for two purposes at the same time; it won't work. – Jonathan Leffler Jan 04 '21 at 15:35
  • 1
    Also, IMO, the first program is extraneous — it should not be part of your question. Removing words is radically different from removing characters. Even trying to enter a single-character word to be removed (e.g. "a") won't work the same as removing the character 'a' because "banana" won't be changed but needs to be. – Jonathan Leffler Jan 04 '21 at 15:39
  • @JonathanLeffler Thanks for answer, i made all the changes you specified, however i still don't know why i get comparison between pointer and integer for the for loop, should i cast something? thanks – Ahmed Montasser Rossafi Jan 04 '21 at 15:40
  • No; you should not cast something. You should look at the comparison and work out what it is doing. The compiler tells you it is comparing a pointer and an integer, and it is right. Which variable is the pointer, and which the integer? What should you be trying to do? Looking at each character up to the first null byte? That's not what your test checks! – Jonathan Leffler Jan 04 '21 at 15:43
  • Your picture of the error messages is unreadable as it stands — though it becomes readable if you click on it on a big enough monitor. Don't post text as images; post the text. Given the multitude of problems in the code, this is perhaps one of the less serious issues this time, but in general, it is a bad idea to post images of text. It is very hard to read on a mobile device, for example. – Jonathan Leffler Jan 04 '21 at 15:48

1 Answers1

3

You can read the file character by character and only save those that don't match the character you want to remove.

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

    int main(void)
    {
        int c = 0;
        const unsigned char discard = 'a';
        const char *file_name = "input.txt";
        FILE *input_file = NULL, *output_file = NULL;
    
        if (!(input_file = fopen(file_name,"r")) || !(output_file = fopen("out.txt","w"))) /* Checking if the file pointers are NULL */
        {
           fprintf(stderr,"error handling"); /* Add error messages */
            exit(EXIT_FAILURE);
        }
    
        while ((c = fgetc(input_file)) != EOF)
        {
            if (c != discard)
            {
                fputc(c,output_file);
            }
        }

        fclose(input_file);
            
        exit(EXIT_SUCCESS);
    }
alex01011
  • 1,670
  • 2
  • 5
  • 17