• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 406
  • Last Modified:

reading and modifying a file in C

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
matu007
Asked:
matu007
2 Solutions
 
shivsaCommented:
0
 
shivsaCommented:
/* 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
 
matu007Author Commented:
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
Has Powershell sent you back into the Stone Age?

If managing Active Directory using Windows Powershell® is making you feel like you stepped back in time, you are not alone.  For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why.

 
sunnycoderCommented:
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
 
sunnycoderCommented:
the second code snippet appends an a to the end of each file
0
 
shivsaCommented:
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
 
sunnycoderCommented:
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
 
rstaveleyCommented:
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
 
itchi-itchiCommented:
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
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now