Soumyajit Roy
Soumyajit Roy

Reputation: 463

Trying to find and replace a string from file

    void replaceString(char* file, char* str, char* replace)
    {
        FILE* fp = fopen(file,"rt");
        char buffer[BUFFER];
        while(fgets(buffer,BUFFER,fp)!=NULL)
        {
            char* s;
            s=strstr(buffer,str);
            if(s!=NULL)
            {
                strcpy(s,replace);
                printf("%s is replaced by %s\n",str,replace);
            }
        }
        fclose(fp);
    }

    int main(int argc, char **argv)
    {
        char* file= "text.txt";
        replaceString(file,"is","was");
        printFile(file);
        return 0;
    }

Guys I am new to file operations, trying to find and replace a string by another. please help! I am trying to open the file in "rt" mode. Saw this in some example code. Not sure about the mode. I am guessing that I need to use a temp.txt file to do that! Can it be done in a single file without using any other file?

Upvotes: 1

Views: 34214

Answers (4)

Mohsin
Mohsin

Reputation: 732

"rt" mode is for read only. Use "r+" mode. That opens the file for both read and write.

Upvotes: 0

taneryilmaz
taneryilmaz

Reputation: 442

This code replaces all occurences of 'orig' text. You can modify as your needing:

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

static void
replaceAllString(char *buf, const char *orig, const char *replace)
{
    int olen, rlen;
    char *s, *d;
    char *tmpbuf;

    if (!buf || !*buf || !orig || !*orig || !replace)
        return;

    tmpbuf = malloc(strlen(buf) + 1);
    if (tmpbuf == NULL)
        return;


    olen = strlen(orig);
    rlen = strlen(replace);

    s = buf;
    d = tmpbuf;

    while (*s) {
        if (strncmp(s, orig, olen) == 0) {
            strcpy(d, replace);
            s += olen;
            d += rlen;
        }
        else
            *d++ = *s++;
    }

    *d = '\0';

    strcpy(buf, tmpbuf);
    free(tmpbuf);
}

int
main(int argc, char **argv)
{
    char str[] = "malatya istanbul madrid newyork";

    replaceString(str, "malatya", "ankara");
    printf("%s\n", str);
    replaceString(str, "madrid", "tokyo");
    printf("%s\n", str);

    return 0;
}

Upvotes: 2

rabensky
rabensky

Reputation: 2934

Here are some of the errors in your algorithm.

  • You read and look at one BUFFER of chars at a time, with no overlap. What if str appears between buffers? (i.e. the first part of str is at the end of a buffer and the second part is at the start of the next buffer).

  • You try to overwrite str with replace directly in the buffer using strcpy. What if both strings are of different length? If replace is shorter than str, you'd still have the end of str there and if replace is longer, it will overwrite the text following str

  • Even if they are the same length, strcpy adds the final 0 char at the end of the copy (that's how they tell you where the string ended). you DEFINITIVELY don't want that. Maybe strncpy is a better suggestion here, although it will still not work if both strings aren't the same length.

  • You replace the strings in the buffer but do nothing with the "corrected" buffer! The buffer is not the file, the content of the file was COPIED into the buffer. So you changed the copy and then nothing. The file will not change. You need to write your changes into a file, preferably a different one.

Writing such a replace isn't as trivial as you might think. I may try and help you, but it might be a bit over your head if you're just trying to learn working with files and are still not fully comfortable with strings.

Doing the replace in a single file is easy if you have enough memory to read the entire file at once (if BUFFER is larger than the file size), but very tricky if not especially in your case where replace is longer than str.

Upvotes: 2

Niklas Rosencrantz
Niklas Rosencrantz

Reputation: 26647

I'd look at using a buffer and work on this.

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

int main ( ) {
    char buff[BUFSIZ];      // the input line
    char newbuff[BUFSIZ];   // the results of any editing
    char findme[] = "hello";
    char replacewith[] = "world";
    FILE *in, *out;

    in = fopen( "file.txt", "r" );
    out= fopen( "new.txt", "w" );

    while ( fgets( buff, BUFSIZ, in ) != NULL ) {
        if ( strstr( buff, findme ) != NULL ) {
            // do 1 or more replacements
            // the result should be placed in newbuff
            // just watch you dont overflow newbuff...
        } else {
            // nothing to do - the input line is the output line
            strcpy( newbuff, buff );
        }
        fputs( newbuff, out );
    }

    fclose( in );
    fclose( out );
    return 0;
}

Upvotes: 0

Related Questions