Writing and Reading from a file at the same time

18,230

Solution 1

There are three main problems with your code:

  1. Opening the file with mode "w+" truncates the file (removes all contents). You can both read and write to it, but the original contents are lost. Mode "r+" would open it for reading and writing without changing the contents, and with the file position initially at the beginning of the file.

  2. It is not safe to perform arithmetic on a value of type fpos_t. It's anyway needless; there's an easier way to move the file position a relative amount.

  3. You do not close the file when you're done.

This variation on your code works for me:

#include <stdio.h>

int main(void)
{
   FILE* filePtr = fopen("text.txt", "r+");
   char c;

   while((c = fgetc(filePtr)) != EOF)
   {
       if(c == '\t')
       {
           fseek(filePtr, -1, SEEK_CUR);
           fputc(' ', filePtr);
       }
   }
   fclose(filePtr);
   return 0;
}

Solution 2

Quoting cplusplus.com,

"w+" write/update: Create an empty file and open it for update (both for input and output). If a file with the same name already exists its contents are discarded and the file is treated as a new empty file.

You should use "r+".

"r+" read/update: Open a file for update (both for input and output). The file must exist.

Solution 3

There are two main problems with the code here:

  1. "r+" mode must be used here instead of "w+".

The "w+" mode deletes all the contents of a file if it exits from before and then writes to the file, while the "r+" mode enables you to use the present data from before.

  1. A position setting function must be used when switching from either reading to writing or from writing to reading data.

From Pelles C help file:

When a file is opened with update mode ('+' as the second or third character in the mode argument), both input and output may be performed on the associated stream. However, output shall not be directly followed by input without an intervening call to the fflush function or to a file positioning function (fseek, fsetpos, or rewind), and input shall not be directly followed by output without an intervening call to a file positioning function, unless the input operation encounters end-of-file.

This is the code that worked for me:

int main(void)
{
    FILE* filePtr = fopen("text.txt", "r+");
    char c;
    while( (c = fgetc(filePtr)) != EOF )
    {
        if(c == '\t')
        {
            fseek(filePtr, -1, SEEK_CUR);
            fputc(' ', filePtr);
            fseek(filePtr, 0, SEEK_CUR);
        }
    }

    fclose(filePtr)
    return 0;
}
Share:
18,230
Anas Ayubi
Author by

Anas Ayubi

Updated on June 25, 2022

Comments

  • Anas Ayubi
    Anas Ayubi almost 2 years

    I've been trying to read and write from a file at the same time and I'm trying to substitute all the tabs in the content of text.txt to be turned into spaces. This is my code:

    int main()
    {
       FILE* filePtr = fopen("text.txt", "w+");
    
       char c;
       c = fgetc(filePtr);
       fpos_t num;
       while(c != EOF)
       {
           if(c == '\t')
           {
               fgetpos(filePtr, &num);
               num--;
               fsetpos(filePtr, &num);
               fputc(' ', filePtr);
           }
           c = fgetc(filePtr);
       }
    }
    

    The content of text.txt is as such:

    Hi \t my \t name \t is \t jack!

    When I run this code, my output in the text.txt file is just blank space. There are no characters there. What should I do so that the substitutions work out as intended?

  • Anas Ayubi
    Anas Ayubi about 9 years
    There is no such thing as nun.__pos
  • utarid
    utarid about 9 years
    \t is tab. Your text has tab or do you really write \t ?
  • Amina
    Amina about 9 years
    Where's fpos_t defined? If I use your version, every first character of every word is erased.
  • Anas Ayubi
    Anas Ayubi about 9 years
    \t is a tab character
  • John Bollinger
    John Bollinger about 9 years
    @AnasAyubi, I'm glad you found a solution. However, if indeed the code I posted does not correctly do the job you described for you, then you have a serious problem in your C implementation.