Search code examples
cfileread-write

How do I replace line-by-line text of a file in C?


I have been researching this for a while and haven't been able to find anything that helps my specific case.

I have a function in which I need to encrypt text in a file. What I want to do is to read a line from a text file and store it into a string, run an encryption algorithm on the string and write the encrypted content of the string back into to the file. That is, I want to replace the file's current line with the encrypted line.

Here is what I have so far:

int encrypt_file(char file_name[]) {
    FILE* file = fopen(file_name, "r+");

    if (file) {
        char line[300];
        while ((fgets(line, sizeof(line), file)) != NULL) {
            fseek(file, -(strlen(line)), SEEK_CUR);
            encrypt_string(line);
            if (fputs(line, file) == EOF) {
                printf("Error. Please try again.\n");
                fclose(file);
                return 1;
            }
        }
        fclose(file);
        return 0;
    } else {
        printf("Error. Ensure file exists and try again.\n");
        return 1;
    }
    fclose(file);
    return 0;
}

To explain my logic, I read the line from the file and then use fseek to move the pointer back by however many characters were read (it should now be at the beginning of the line). I then run the algorithm and then write the new string back into the file.

However, this code gives me an infinite loop. When I remove the fseek, it doesn't give me an infinite loop and it shows me that the algorithm has been correctly used on the string, but it shows the "Error. Please try again.\n" response and no changes have been made to the file itself.

Any help is appreciated.


Solution

  • There was an answer posted here that helped solve my issue. I'm not sure why it has been deleted but if anyone was wondering, it was suggested that I use ftell to keep track of where the pointer should be. This is the code I have now, and it works as intended (the #ifdef statements were just to find out what was going wrong, and are not necessary for the code to work):

    int encrypt_file (char file_name[]) {
        FILE* file = fopen(file_name, "r+");
        long fileindex = 0;
    
        if (file) {
            char line[300];
            while ((fgets(line, sizeof(line), file)) != NULL) {
                #ifdef DEBUG
                    printf("Input: %s", line);
                    char* p = strchr(line, '\n');
                    if (!p) {
                        printf("\n");
                    }
                #endif
    
                fseek(file, fileindex, SEEK_SET);
                encrypt_string(line);
    
                #ifdef DEBUG
                    printf("Output: %s\n", line);
                #endif
    
                if (fputs(line, file) == EOF) {
                    printf("Error. Please try again.\n");
                    fclose(file);
                    return 1;
                }
                fileindex = ftell(file);
                fseek(file, 0, SEEK_CUR);
            }
            fclose(file);
            return 0;
        }
        else {
            printf("Error. Ensure file exists and try again.\n");
            return 1;
        }
    
        fclose(file);
        return 0;
    }