Search code examples
cfile-handlingfwritefreadfseek

Is there a way to change a single line of a file with fseek()?


I'm training file handling in C and I am trying to change a single line or position of the file with fseek() while writing and reading with fread() and fwrite() without changing a variable and writing the whole file again, but apparently neither append mode nor write mode let you do this as I've tried with the example below:

void main()
{
    FILE *file;
    char answer;
    char text[7]  = "text 1\n";
    char text2[7] = "text 2\n";

    file = fopen("fseek.txt", "w"); //creating 'source' file
    fwrite(text, sizeof(char), sizeof(text), file);
    fwrite(text, sizeof(char), sizeof(text), file);
    fwrite(text, sizeof(char), sizeof(text), file);
    fclose(file);

    scanf("%c", &answer);

    switch(answer)
    {
    case 'a':
        //attempt to change single line with append mode
        file = fopen("fseek.txt", "a");
        fseek(file, 7, SEEK_SET); //7 characters offset is the second line of the file
        fwrite(text2, sizeof(char), sizeof(text), file);
        fclose(file);
        break;
    case 'w':
        //attempt to change single line with write mode
        file = fopen("fseek.txt", "w");
        fseek(file, 7, SEEK_SET); //7 characters offset is the second line of the file
        fwrite(text2, sizeof(char), sizeof(text), file);
        fclose(file);
        break;
    }
}

But with append mode it just writes the variable on the end of the file even with the fseek() function beforehand and write mode just erases the file and rewrites it. So how would I change a single line of a file using fseek() or similars ?


Solution

  • You need to open in r+ mode. w mode empties the file first, r doesn't, since it's for reading the file. The + modifier allows you to write the file as well.

    When you change the line, the new text needs to be the same length as the original line. If it's shorter, the remainder of the original line will be left in the file. If it's longer, you'll overwrite the beginning of the next line.