Edit txt file using library from C

348 Views Asked by At

I am facing problems scanning an existing file.

The challenge is that I have a source text file with some strings. I have to scan this file for the word "o'clock", and where I find it, I have to take the word before "o'clock" and enclose it in square brackets.

I found a function to find the trigger, but I don't understand what I need to do next. I would be grateful if you could explain how to replace the characters in the read string.

For example: We have a string:

"Let's go to the graveyard at night - at twelve o'clock!"

I need to replace the word twelve with [twelve].

Here is the code:

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

int main() {
    FILE * fp; //open exists file
    FILE * fn; //open empty file
    char c[1000]; // buffer
    char trigger[] = "o'clock"; // the word before which the characters should be added
    char name [] = "startFile.txt"; // name of source file
    char secondName[] = "newFile.txt"; // name of output file
    fp = fopen (name, "r"); // open only for reading
    if (fp == NULL) { // testing on exists
        printf ( "Error");
        getchar ();
        return 0;
    }
    fn = fopen(secondName, "w"); // open empty file for writing
    while (!feof(fp)) { // scanning all string in the source
        if(fgets(c,1000, fp) != NULL) { // reading charter from file
            fprintf(fn, c); // writing charter from buffer "c" to empty file
            if (strstr(c, trigger)) { // find triggered word
                // I tried compare string which has a trigger-word
            }
        }
    }

    fclose(fp); // closing file
    fclose(fn);
    return 0;
}
1

There are 1 best solutions below

8
On BEST ANSWER

In your code, you copy the line to the output file and then, afterwards, look for the trigger word. But the goal is to find the trigger and edit the string, and only then write the line to the output file. Also, in order to edit the line, you need to know where the trigger was found so you need to save the output of the search.

So, instead of:

    fprintf(fn, c); // writing charter from buffer "c" to empty file
    if (strstr(c, trigger)) { // find triggered word
        // I tried compare string which has a trigger-word
    }

We need:

    char *p = strstr(c, trigger);
    if (p) {
        // I tried compare string which has a trigger-word
    }
    fputs(c, fn); // writing charter from buffer "c" to empty file

So now we found the trigger and we need to search backwards to find the end and then the start of the word before it. When we find them we need to create a spot and insert the edits:

    char *p = strstr(c, trigger);
    if (p) {
        // ok we found the trigger - now we need to search backwards
        // to find the end and then the start of the word before
        while (p>c && p[-1]==' ') p--; // find the end of the word
        memmove(p+1, p, c+999 - p); // make a space for the ]
        *p = ']';
        while (p>c && p[-1]!=' ') p--; // find the start of the word
        memmove(p+1, p, c+999 - p); // make a space for the [
        *p = '[';
    }
    fputs(c, fn); // writing charter from buffer "c" to empty file

Try it here: https://www.onlinegdb.com/H18Tgy9xu

But then, what if there was more than one "o-clock" in the string? Something like this:

Let's go to the graveyard at twelve o'clock and have dinner at six o'clock beforehand!

In that case, you need to loop around until you have found all of them:

Here is the final code:

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

int main() {
    FILE * fp; //open exists file
    FILE * fn; //open empty file
    char c[1000]; // buffer
    char trigger[] = "o'clock"; // the word before which the characters should be added
    char name [] = "startFile.txt"; // name of source file
    char secondName[] = "newFile.txt"; // name of output file
    fp = fopen (name, "r"); // open only for reading
    if (fp == NULL) { // testing on exists
        printf ( "Error");
        getchar ();
        return 0;
    }
    fn = fopen(secondName, "w"); // open empty file for writing
    if (fn == NULL) { // testing on create
        printf ( "Error");
        getchar ();
        return 0;
    }
    while (fgets(c, 1000, fp)) { // scanning all string in the source
        char *p = c; // we need to start searching at the beginning
        do {
            p = strstr(p+1, trigger); // find the next oclock after this one
            if (p) {
                // ok we found the trigger - now we need to search backwards
                // to find the end and then the start of the word before
                while (p>c && p[-1]==' ') p--; // find the end of the word
                memmove(p+1, p, c+999 - p); // make a space for the ]
                *p = ']';
                while (p>c && p[-1]!=' ') p--; // find the start of the word
                memmove(p+1, p, c+999 - p); // make a space for the [
                *p = '[';
                p = strstr(p, trigger); // find that same oclock again
                // (we couldn't save the location because memmove has changed where it is)
            }
        } while (p); // as long as we found one, search again
        fputs(c, fn); // writing charter from buffer "c" to empty file
    }
    fclose(fp); // closing file
    fclose(fn);
    return 0;
}

Try it here: https://onlinegdb.com/SJMrP15ld