Home > Software engineering >  How to append any character to file when using ' r ' mode in file IO in C
How to append any character to file when using ' r ' mode in file IO in C

Time:04-19

#include <stdio.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>

int main(){
    printf("Hii!\n");
    //printf("Enter your student ID: ");
    //int stdID;
    //scanf("%d", &stdID);
    //printf("Enter the book ID\n");
    //int bookID;
    //scanf("%d", &bookID);
    FILE *in_file = fopen("unique.txt", "r ");

    struct stat sb;
    stat("unique.txt", &sb);

    char *file_contents = malloc(sb.st_size);

    while (fscanf(in_file, "%[^\n] ", file_contents) != EOF) {
        int size = strlen(file_contents);
        printf("%d\n", size);
        for(int i=0; i<size; i  ){
             printf("%c", file_contents[i]);
             if(file_contents[i] == 'r'){
                 file_contents[i] = 'q';
             }
        }
        printf("\n");
        printf("> %s\n", file_contents);
    }

    fclose(in_file);
    return 0;
}

In this program I tried to read the contents of file line by line and tried to replace the character 'r' with 'q'. It updates in the string part but not in the file. If I want to update in file too then for that can anyone suggest possible ways? Thanks in Advance!!

Output: Terminal: Terminal output

File after running the program(no change): Screenshot of file after running program

CodePudding user response:

Check out file-opening mode r the example "C program for opening file in r mode". You need to call fprintf() or fputc() at some point to write into the file, printf() only prints to the console with no effect on the file.

For your example you want to read the characters not at once, but in order with fgetc(), then change the 'r' to a 'q' with fputc(). A little less pretty would be to overwrite the file with fprintf() with filecontents for each line.

CodePudding user response:

You are not actually printing nothing to the file, you are just modifying the string in RAM without updating the file. A simple workaround would require to use fseek and ftell.

#include <stdio.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

int main(){
    printf("Hii!\n");
    FILE *in_file = fopen("unique.txt", "r ");

    struct stat sb;
    stat("unique.txt", &sb);

    char *file_contents = malloc(sb.st_size);

    while (fscanf(in_file, "%[^\n] ", file_contents) != EOF) {
        int size = strlen(file_contents);
        long line_start_position = ftell(in_file) - size - 1;
        bool updated = false;
        printf("%d\n", size);
        for(int i=0; i<size; i  ){
            printf("%c", file_contents[i]);
            if(file_contents[i] == 'r'){
                file_contents[i] = 'q';
                updated = true;
            }
        }
        if (updated) {
            fseek(in_file, line_start_position, SEEK_SET);
            fputs(file_contents, in_file);
        }
        printf("\n");
        printf("> %s\n", file_contents);
    }

    fclose(in_file);
    return 0;
}

Each time you read a line from the file, you keep the position in the file where the line starts, so that you can go back there to rewrite the whole line if it needed an update.

If you wanted to update single characters, you need to read single characters from the file (with fgetc) and, if they need to be changed, move back the cursor with fseek(in_file, -1, SEEK_CUR) and rewrite them with fputc.

  • Related