Solved

reading and modifying a file in C

Posted on 2003-11-21
12
393 Views
Last Modified: 2010-08-05
Hi ,
I have a file of the following format

8366 , 6699 , 1
10520 , 5145 , 1
4503 , 7473 , 1
10365 , 9453 , 1

depending upon a certain condition i need to be able to
modify the third field i.e the "1" field and increment its value by 1 or 2 or whatever .


How should i read this file and modify the field (i.e. write the value back to the file ), i can use functions like fseek and ftell pos but i dont know exactly how to go about the whole process,


thanks
matu

0
Comment
Question by:matu007
12 Comments
 
LVL 24

Accepted Solution

by:
shivsa earned 180 total points
ID: 9801200
0
 
LVL 24

Expert Comment

by:shivsa
ID: 9801312
/* This is outline, if u know more then get the idea and complete the code. */
/* This will change last charecter of a line in a file to 'a' */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
main(){
char ch;
FILE *fp;
long pos;

fp=fopen("exp.dat","r+");

fseek(fp,0,SEEK_SET);
while((ch = fgetc(fp))!='\n');

pos = ftell(fp);   /* now u got the position of last charecter in the line */

pos2 = pos -2; /* we have to go back 2 charecter, last one is \n and before that we have to replacement */
/* now u got the position of last charecter in the line */

/* code whatever condition u are checking  to increase by 1 or 2 */

fseek(fp,pos-2,SEEK_SET);
fputc('a',fp); /* I am changing the last charecter to a */
}
0
 

Author Comment

by:matu007
ID: 9801383
Can i get a solution for scrolling thriough the whole file , also it does not replace the last character but write an 'a' to the end after the last character.I tried "pos = pos-4" and then it works for one line replacing the '1' by an 'a' but i am not sure wether it will work for the other lines.IS it necessary that the newline character will be immediately next to the last character in the line??

By the way i have tried

int main(void)

{

    char ch;
    FILE *fp;
    long pos;
    long pos2;
   

    fp=fopen("new.doc","r+");
    fseek(fp,0,SEEK_SET);
   
      while(!feof(fp))    //Addition ??? IS this right
            {
               
             while((ch = fgetc(fp))!='\n');

                 pos = ftell(fp);  /* now u got the position of last charecter in the line */
                 pos2 = pos -2;    /* we have to go back 2 charecter, last one is \n and before that we have to replacement */
                 /* now u got the position of last charecter in the line */
       
                 /* code whatever condition u are checking  to increase by 1 or 2 */

                  fseek(fp,pos2,SEEK_SET);
                  fputc('a',fp);
            }
    return 0;
}
0
 
LVL 45

Assisted Solution

by:sunnycoder
sunnycoder earned 180 total points
ID: 9801587
Hi matu007,

While it is possible to replace a char in the file with another one, it is not recommended for simple reason that if your replacement string is bigger in size than the original string, your useful data will get overwritten ... If you suspect that such a situation may arise, you should use a temporary file ...

char buffer[256];
char * temp;
infile = fopen ( "inputfile", "r" );
outfile = fopen ( "outfile", "w" );

while ( fgets ( buffer, 256, infile ) != NULL )
{
           temp = strrchr ( buffer, ',' ); /*locate the last , in the line*/
           temp = temp+2;              /* single blank space */
           * temp = 'x';     /* replace value with x or add chars or do whatever you like ... make sure that there is a end of string present*/
           fputs ( buffer, outfile );
}

fclose (infile);
fclose (outfile);

char buffer[256];
char * temp;
infile = fopen ( "inputfile", "r" );
outfile = fopen ( "outfile", "w" );

while ( fgets ( buffer, 256, infile ) != NULL )
{
           temp = buffer + strlen ( buffer );
           * temp = 'a'; /* make sure that there is a end of string present*/
           * (temp + 1) = '\n';
           * (temp + 2 ) = 0;
           fputs ( buffer, outfile );
}

fclose (infile);
fclose (outfile);
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 45

Expert Comment

by:sunnycoder
ID: 9801590
the second code snippet appends an a to the end of each file
0
 
LVL 24

Expert Comment

by:shivsa
ID: 9801875
here is complete solution.
----------------------------------
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

main(){
char ch;
FILE *fp;

long pos;
long i,j;
char tmp_str[8];

fp = fopen("/tmp/1","r+");

i=0;
while ((ch=fgetc(fp)) != EOF ) {
     i++;
     if(ch == '\n'){

          pos=ftell(fp);

          j=2;    /* u have to go back atleast 2 since fgetc move when it read one char, and we have encounter \n too */

          fseek(fp,(long)(i-j), SEEK_SET);

          while (i !=0 ){       /* go till u find a digit */
          if(!isdigit(ch=fgetc(fp))) {          /* check char if it digit backward starting from end of line*/
               j = j+1;
               fseek(fp,(long)(i-j), SEEK_SET);
          }
          else{          /* we got end digit */
               tmp_str[0]=ch;
               tmp_str[1]='\0';
               num = atoi(tmp_str);
               num = num +1;
               ch = (char)(num +48);    /* Ascii char are offset by 48 wrt num */
               fseek(fp,(long)(i-j), SEEK_SET);
               fputc(ch,fp);
               break;
          }
          }          
          fseek(fp,(long)(pos), SEEK_SET);
     }
         
}
}
0
 
LVL 45

Expert Comment

by:sunnycoder
ID: 9801936
compare with this

#include <stdio.h>
#include <string.h>

int main ()
{
      char buffer[256];
      char * temp;
      FILE * infile, *outfile;

      infile = fopen ( "inputfile", "r" );     /* open the files */
      outfile = fopen ( "outputfile", "w" );

      while ( fgets ( buffer, 256, infile ) != NULL )    /* read in line by line */
      {
             temp = buffer + strlen ( buffer );        /* get length of line read and make temp point to the end  */
             * temp = 'a'; /* append a to buffer*/
             * (temp + 1) = '\n';  /* end the string properly */
             * (temp + 2 ) = 0;
             fputs ( buffer, outfile );
      }

      fclose (infile);
      fclose (outfile);
}
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 9804421
Presumably you need to interpret the values to decide what to do with the 3rd field. Here's a skeleton for a program which takes input from STDIN and outputs to STDOUT. This tokenises the input expecting integers separated by commas and/or spaces and passes the integers to a doit function. You could put your logic into doit.

--------8<--------
/*
    Usage:
        ./a.out < inputfile > outputfile
 */

#include <stdio.h>
#include <string.h>

void doit(int,int,int,int);

int main()
{
int a,b,c,line = 0;
char buf[256],*cptr;
static char seps[] = ", "; /* Commas and spaces treated as separation between tokens */

/* Read line from input and interpret the tokens */

        while (fgets(buf,sizeof(buf),stdin)) {
                ++line;
                if (cptr = strtok(buf,seps)) {
                        a = atoi(cptr);
                        if (cptr = strtok(NULL,seps)) {
                                b = atoi(cptr);
                                if (cptr = strtok(NULL,seps)) {
                                        c = atoi(cptr);
                                        doit(line,a,b,c);
                                }
                        }
                }
        }
}

/* Function is passed the line number and the three integer fields from the input */
void doit(int line,int a,int b,int c)
{

/* Here's where you put your logic. I'm just going to
   increment c in my example. You might base your logic
   on line number or the values of a, b and c */

        c++;

/* Write revised integers to the output */

        fprintf(stdout,"%d , %d , %d\n",a,b,c);
}
--------8<--------
0
 
LVL 1

Expert Comment

by:itchi-itchi
ID: 9955209
try this..
first store all the records in memory
then overwrite the file.


************************************************************

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(){

  // first read the data file
  FILE *source;
  if((source = fopen("data.txt", "r")) == NULL)
    printf("Can't open file. Bad Filename.");

   char str_temp[50];
   int no_of_records=0;

   while(!feof(source)){
      fgets(str_temp, sizeof(str_temp), source);
       no_of_records++;
   } rewind(source);


   // allocate memory to store all records
   int **storage;
   if((storage = (int **) malloc(no_of_records * 3 * sizeof(int))) == NULL)
      printf("Not enough memory space.");
   for(int i=0; i<no_of_records; i++)
      storage[i] = (int *) malloc(3 * sizeof(int));


   // store records to array
   for(int i=0; i<no_of_records; i++){
      fscanf(source, "%d, %d, %d", &storage[i][0], &storage[i][1], storage[i][2]);
     
      // manipulate the last field
      storage[i][2]++;
   } fclose(source);


   // reopen the source to overwrite
   if((source = fopen("data.txt", "w")) == NULL)
         printf("File access denied.");

   for(int i=0; i<no_of_records; i++){
      fprintf(source, "%d, %d, %d", storage[i][0], storage[i][1], storage[i][2]);
      if(i != (no_of_records-1)) fprintf(source, "\n");
   }
   fclose(source);

free(storage);
}
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
The goal of this video is to provide viewers with basic examples to understand and use structures in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use while-loops in the C programming language.

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now