Link to home
Start Free TrialLog in
Avatar of srik18
srik18

asked on

Read and Write to a file.

Hi,
I need to read a line from the file.
Delete the line.
And then remove the space( that is move the lines below the deleted line by one line up).

That is suppose i have a file called exp.dat which contains 3 lines of information...
like
1 wejrn 1234
1 blah bhal
3 blaaa nmk

i want to delete the first line and move the second line to first line and third line to second line respectively.

i dont know what mistake i am making....must be with the file mode!!
 
below is the code that i wrote.
/***************segment of code***********/

char ch;
FILE *fp;
long pos;
fp=fopen("exp.dat","r+");

ch = fgetc(fp);
while(ch!='\n')
{
pos=ftell(fp);
fseek(fp,pos-1,SEEK_SET);
fputc(32,fp);
ch = getc(fp);
}


The above code is for reading a character and replacing it with space. I havent written code for moving the 2 lines below it by one line. Also tell me how to move the lines up.
Thanx in advance.
S.
Avatar of sunnycoder
sunnycoder
Flag of India image

Hi srik18,

the best way to do this would be to open a temporary file and write modified information to that file ... after you have finished editing, replace original file with the temporary file ...

we had discussed this question some time ago... you can find all this information here
https://www.experts-exchange.com/questions/20740087/i-need-to-readline-from-file-and-overwrite-the-line-in-the-file.html

Cheers!
Sunny
Avatar of srik18
srik18

ASKER

Hi Sunny,
I thought about that earlier also....but i dont want to do it that way. i want to write to the same file due to some constraints.
Thanx for your quick reply though.  Can you suggest something else?

S.
there is no standard file operations that will do line scrolling for you, u either need to read the file to a temporary file OR read it in memory..
SO if u want to write to the same file, and the file isnt that big... u can read the lines in the memory, using multiple calls to
fgets() look man page..
then skip the first line and then.. reopen the file in write mode...and write the lines back..
OR open the file in append mode.. then after u are done loading the lines in the memory, then reset the file pointer to the start and write back the lines.

btw could you elaborate on ur constraints.. that will help us to suggest u best possible solution
Akshay
Hi Srik18,

while replacing the first line with spaces might be easier, moving the trailing lines up is definitely not trivial nor is it a good idea ... I would stick to my suggestion - use a temporary file which akshay has reinforced... You will find a helpful discussion in the link posted above (link includes methods to accomplish both the tasks and reasons as to why temoprary file approach is better)

Cheers
Sunny
sorry missed a point,
once u have finished reading the file in the memory, u must reopen the file in 'w' mode
like this
fp=freopen("path","w",fp);

ASKER CERTIFIED SOLUTION
Avatar of akshayxx
akshayxx
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
above code worked fine , but may be u shud call
fclose(fp);
just before calling truncate.
hope this helps.
Akshay
u may not find truncate function on many systems, as its part of 4.4 BSD norms, but u will find ftruncate function on systems following POSIX standard.. ftruncate takes file descriptor argument, instead of the file path.

and one more thing, u shud add some error handling stuff, if u intend to use the above code.
btw we are still waiting for ur 'constraints'
You can open the same file on two different file handles, each maintaining its
own buffer an file position.  This allows you to do it without seeking:

#include <stdio.h>
#include <unistd.h>

int main(int argc, char **argv)
{
  FILE * fin = fopen(argv[1], "r");      // open the same file as input and output
  FILE * fout = fopen(argv[1], "r+");
  char buffer[4096];

  fgets(buffer, sizeof(buffer), fin);   // read first line & discard it

  // copy lines from input to output
  while (fgets(buffer, sizeof(buffer), fin))
    fputs(buffer, fout);

  fclose(fin);
  ftruncate(fileno(fout), ftell(fout)); // truncate the output
  fclose(fout);

  return 0;
}

brett:.. two different handles on same file might have some problems, as when u are making write calls to the file, first it will be buffered, but at some points buffer will be automatically flushed to the file, that might be a problem for the termination condition for the read loop on the read handle.
> two different handles on same file might have some problems, as when u are making write calls to the file,
> first it will be buffered, but at some points buffer will be automatically flushed to the file, that might be a
> problem for the termination condition for the read loop on the read handle.

Not in this case.  In the case where the file is shrinking, we are writing over portions of the file that have already
been read - even in the buffered case.  If you tried to insert a line into the file (expanding it) neither of the
above solutions will work.


Avatar of srik18

ASKER

Hi Ppl,
Thank you very much for the help.
Sorry for the late reply.
I am going to go with Akshay's solution. I was also thinking about opening 2 file pointers and although that is a good solution. Because Akshay was the first to reply i am going to go with him.
Thanks to everyone for their effort.
Regards,
S.
thanks,
if u like more than one ppl helped you, you always have option to split up.
anyways good to know it helped.