Solved

reading and modifying a file in C

Posted on 2003-11-21
12
400 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
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
 
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

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
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 pointers in the C programming language.
The goal of this video is to provide viewers with basic examples to understand opening and reading files in the C programming language.
Suggested Courses

617 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