Hey, this one is agaain from File-handling

How do you replace a word in a file with another word.
The algorithm should be somewhat like this

1)Read (fgets) the entire line into a buffer. Locate the word/ position of the word.
2)From that point onwards, OVERWRITE the contents in the buffer with the NEW WORD.
3)Put (fprintf) the modified buffer back into the file.

Fine BUT, doesnt this just shout out that, it'll work only if the word-to-be-replaced and the new-word are of the same length. Otherwise,(assuming the new word is higher in length) to accommodate the new word, it'll over-write over a part of the file which is actually necessary.

Sample Output of error case
---------------------------

File contents : goodsite
Replace good with great
File contents : greatite - WRONG
Expected correct output :greatsite

Please give me your valuable suggestions

Dani AI

Generated

Good instincts, — the simple, safe and portable solution is to write a new file and then replace the original. That avoids expensive in-place byte-shifts and handles arbitrary length changes. 's point about "how do you know the word ended" is important: you must decide whether you replace substrings or whole words, and define word boundaries (spaces, punctuation, start/end-of-file, locale rules).

Practical checklist

  • Decide rule for a match: exact substring vs whole word. For whole-word checks, test the character before and after the match with isalnum()/isalpha() (or your locale rule) to avoid replacing inside other words.
  • Stream the file: read blocks, search for the pattern, write preceding bytes to the temp file, write the replacement, skip the matched bytes in the input, continue. Keep the last (pattern_length-1) bytes between reads to handle matches spanning buffer boundaries.
  • Use a temp file on the same filesystem (so rename() is atomic on POSIX). Check errors and preserve file permissions if needed.

Minimal streaming sketch (conceptual)

/* open in = fopen("file","rb"), out = fopen("file.tmp","wb") */
while ((n = fread(buf,1,BLOCK,in)) > 0) {
  prepend previously saved tail to buf;
  for (i = 0; i <= n - patlen; ++i) {
    if (memcmp(buf+i, pat, patlen) == 0 && is_word_boundary(buf,i,patlen)) {
      fwrite(buf+last, 1, i-last, out);
      fwrite(repl, 1, repl_len, out);
      i += patlen - 1; last = i+1;
    }
  }
  fwrite(buf+last, 1, n-last, out);
  save final (patlen-1) bytes to prepend next loop;
}
rename temp over original;

(Handle EOF, leftover tail, and errors.)

Advanced alternatives

  • If replacement text is exactly same length, open read/write and overwrite in place.
  • In-place expansion is possible by shifting the file tail backwards in block-sized copies (copy from file-end toward the insertion point) and then writing replacement, but it is more complex and requires ftruncate() (or platform equivalent) and careful overlap handling. Use only if you must avoid temp files.

Troubleshooting tips: test with punctuation, multiple occurrences, overlapping patterns (e.g., "ana" in "banana"), and with large files; add file locking if concurrent access is possible.

Recommended Answers

All 4 Replies

Hey, this one is agaain from File-handling

How do you replace a word in a file with another word.
The algorithm should be somewhat like this

1)Read (fgets) the entire line into a buffer. Locate the word/ position of the word.
2)From that point onwards, OVERWRITE the contents in the buffer with the NEW WORD.
3)Put (fprintf) the modified buffer back into the file.

Fine BUT, doesnt this just shout out that, it'll work only if the word-to-be-replaced and the new-word are of the same length. Otherwise,(assuming the new word is higher in length) to accommodate the new word, it'll over-write over a part of the file which is actually necessary.

Sample Output of error case
---------------------------

File contents : goodsite
Replace good with great
File contents : greatite - WRONG
Expected correct output :greatsite

Please give me your valuable suggestions

hey guys, its me again, just struck me now.
Lets assume the case i gave above , replace good with great

How about this
--------------
1)Find the location of word-to-replace ,ie good(in our case), (here first place itself, never mind)
2)Write all the characters until this into a file2(In this case, nothing precedes good, that ok)
3)On encountering the word-to-replace, write the word-with-which-to-replace into the file2
4)Move the pointer of file1 as long as the word-to-replace is over.
5)Then again write the remaining contents into file2
6)Delete file1
7)Rename file2 to file1
For newcomers like me who are reading this some day, YES, both 6 and 7 are very much possible in C

Word of caution
---------------
Sooooooo Brute force.

Please give me your valuable suggestions, if and since there is a better algorithm

Good! Now tell me when you know that the word to replace, has ended?

1) a space is reached, obviously ;)

2) an end of line char is reached, of course

3) what about EOF (end of file), and punctuation char's?

Lots of details when you deal with strings, language, etc. Great start though.

Hey Adak, feels great talking to you.
I actually referred 1 of the posts in which you had posted http://www.daniweb.com/software-development/c/threads/367273. Thanks a lot for that :)

Coming to the problem, how do you know where the word-to-replace has ended, cat we just do a

while(*word-to-replace)
{
 c=getc(fp_file1); //so that the file pointer keeps incrementing
}

I mean everytime you do a getc(fp_file1) , getc points to the next character in the file right ????
Isnt this enough insted of going case-by-case.

Have i understood your comment . I think i have not.
Do reply.

Have you considered using strstr()? It's made for this, imo. Look at it in your help file, and see what you think.

Then make a little test case and program, with strstr(), or with your earlier idea, or both, and see how it works. You know you're close, so it won't be a waste of time. Be sure the test case has some "difficult" text, which includes most or all of the above details discussed herein.

There's always more than one way to do something. If I have a very small number of words, I tend to use a small buffer, and go char by char (ie., small), to do this. If I have a lot of text, then I tend to go with a very big buffer, and use strstr(). I believe you should know how to use either one, depending on what you think is best, at that time, for that problem.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.