?
Solved

How do I add a character into the header file?

Posted on 2003-02-19
26
Medium Priority
?
319 Views
Last Modified: 2010-04-15
Hi experts,
We have a file format, in which we are writing the format version in the header along with some other information. Initially some information is written into the file then followed by the version information. After that, the file data will be written. Now the version is "4.0.2". I would like to introduce a flag in the version for a specific task. In other words, I would like to read the file and if it is "4.0.2", then I would like to make it "4.0.3" or "4.0.2A"

How do I do it without disturbing the file format.

Warm Regards,
Narahari Sanga
0
Comment
Question by:nsanga
[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
  • 7
  • 6
  • 6
  • +3
26 Comments
 
LVL 8

Expert Comment

by:ssnkumar
ID: 7980655
The flat file is a sequential storage and you can not push or delete the data in a file. The only possibility is overwriting!
So, the best way to achive your objective is to read all the contents into a character buffer, close the file and do all the modifications in this buffer itself. After this, open the file again, this time in write mode and write back the buffer to the file and close it.

Hope this works for you....

-Narendra
0
 
LVL 8

Expert Comment

by:akshayxx
ID: 7980762
if u are not worried about doing it programmatically .. then   u can get an easy search/replace script with sed/awk or perl ..
btw what OS u working on
0
 
LVL 5

Expert Comment

by:Kocil
ID: 7985547
to change from 4.0.2 to 4.0.3 is easy,
but not from 4.0.2 to 4.0.2A because it needs 1 more byte => you have to shift the entire file.

This is for the first case.

// assume this is your header
typedef struct {
   char info[100];
   char version[5];
   char other[100]
} THeader;

change(char *fname, char *old, char *new)
{
   static THeader buffer;
   FILE* f=fopen(fname, "w");
   char *pos;
   fread(f, buffer);
   if (strncmp(buffer.version,old,5) == 0) {
      strcpy(buffer.version, new);
      fseek(f,0);
      fwrite(f,buffer);
   }
}

   
main()
{
   change("MyFile", "4.0.2", "4.0.3");
}

0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 5

Expert Comment

by:Kocil
ID: 7985576
Ooops, correction.

change(char *fname, char *old, char *new)
{
  static THeader buffer;
  FILE* f=fopen(fname, "rw");
  fread(buffer, sizeof(THeader), 1, f);
  if (memcmp(buffer.version,old,5) == 0) {
     memcpy(buffer.version, new, 5);
     fseek(f,0,SEEK_SET);
     fwrite(buffer, sizeof(THeader), 1, f);
  }
}

Sorry, no manual inside :)
0
 
LVL 7

Author Comment

by:nsanga
ID: 7991936
Kocil,
Thanks for your suggestion. I will try to implement as you suggested. However, I would like bring some thing into your notice that the data is written in the binary format. Each element is written with the type (as you mentioned in the example, the version will have some type and the number of words to store the version information. This is to read those many bytes for the version and also a flag for internal use).

I assume that I need to open the file in "rwb" mode. Please let me know. I tried this method some time back and couldnot write successfully into the file.

ssnkumar,
Thanks for the info. However, I may not go ahead with this method as there will be lots of data after the header, which requires me to read the entire file and store the information.

Warm regards,
Narahari Sanga
0
 
LVL 12

Expert Comment

by:rajeev_devin
ID: 8014940
Let me hope that your version information takes 5 charaters, sice you have written 4.0.2. Now you want to change the version information without altering the file format, now it may contaion 6 charaters also.

One solution to overcome this problem is to assign a file pointer at that place instead of the version number. The file pointer will indicate the place where the version is stored. I suggest you to store the version informationin the end of the file. In this way you are not going to alter the file format. If you have already written some code to write or read the file, yhen you have to do a little modification there ( not that much ).

Another suggestion is that whenever you design a new file format always consider the future extension of that file. This is very important, that you may realize now.

I am a person working in the field of image processing, and this type of file format designing always comes in our work. If you want further help you can mail me in my personal email id [edited by moderator Mindphaser]. If you want help in this format itself then please specify the file format type, like image file, database file, etc.

Thank you

Hope this may help you.
0
 
LVL 8

Expert Comment

by:ssnkumar
ID: 8015014
>If you want further help you can mail me in my personal email id [edited by moderator Mindphaser].

I am seeing the same comment for 2nd time. Why are you asking them to contact you on your mail id!? Why don't you discuss the answer here itself, so that we also can know the answer...:-)
I don't see any reason for giving your mail ids to questioners and asking them to contact you. You can get the complete code here itself and this forum is open to discussions of any length.....
Please clarify....

-Narendra
0
 
LVL 7

Author Comment

by:nsanga
ID: 8015097
rajeev_devin,
Thanks for the suggestions regarding the format designing. I am working on a legacy product, which is started around 14 years back.

Coming to the solution, I may not go for adding a pointer since we have delivered many versions to the customers and the older versions of the software don't understand the modified format.

Narendra,
I am thinking of reading the entire file (ofcourse, it is a costly operation for me) and writing the contents back with the modified format number.

Experts,
Please suggest a possible solution, if I would like to fix the version number to same number of bytes (e.g. "4.0.3")  

Warm regards,
Narahari Sanga
0
 
LVL 8

Expert Comment

by:ssnkumar
ID: 8015423
Still I am in a confused state... as to what you are actually doing!?:-))
Are you trying:
To change the version number written inside a file?
Or Creating a new file with new version number?

-Narendra
0
 
LVL 8

Expert Comment

by:akshayxx
ID: 8015426
i hope u know the location of this particular string.. as  u say u know the format of the file .. formatting means fixing/knowing the location of various elements
and
also if u want to keep the number of bytes same
what if ur existing version is 4.0.9 .. wud u like it to be
4.1.0 OR 4.0.10 ( in this case number of bytes increased)

what if its 9.9.9 ?

also
to make 4.0.2 to 4.0.3 its pretty easy
char *idx = location of start of "4.0.2" in the big string of file loaded in the memory.

now to make this 4.0.3 just have to do

(*(idx+4))++;
this will make 4.0.2 to 4.0.3

but dont forget about the cases that i said above..
other wise u can do is
int len=strlen("4.0.2");
char * temp=(char*)malloc(len);

memcpy(temp,idx,len);
now process the "4.0.2" string in the temp in the way u wish
and then when u change 'temp' to "4.0.2" OR "4.1.0" IN case of 4.0.9
move the bytes back to main string
memcpy(idx,temp,len);

its that simple .. its really isnt much of a problem..
 if u can show that part of ur file(from start to 4.0.2) ... i can be more precise and give more generic solution


0
 
LVL 7

Author Comment

by:nsanga
ID: 8015596
Narendra,
My intention is to change the value of a field in the header from "4.0.2" to "4.0.3" in the file. I have opened the file in "rwb" mode and read the header till the version number and tried to write "4.0.3". However, it did fail.

Now, I am thinking to read the file (consists of header and "n" number of elements information) and close the file. Then, I will reopen the file and dump everuthing with the modified version number in the header i.e., "4.0.3"

I would like to do this because, I need to apply a different set of conversion routines if a file has "4.0.3" as the version number.

Hope, it is clear now.

Warm regards,
Narahari Sanga
0
 
LVL 12

Expert Comment

by:rajeev_devin
ID: 8015699
I tried this problem in my C code as follows:
1. First I have written the version information in a test file.

FILE *fpt = fopen("test.dat","w+b");
char ver[] = "4.0.2";
fwrite(ver,1,5,fpt);
fclose(fpt);

2. With another program I first read the version to check out the old version number, replaced it with the new version number, and then again read the version number for verification. It is working fine.

/* Write version and data */
     char ver[6];
     FILE *fpt = fopen("test.dat","r+b");

     fread(ver,1,5,fpt);
     ver[5] = '\0';
     printf("%s",ver);

     fseek(fpt,0,SEEK_SET);
     strcpy(ver,"4.0.3");
     fwrite(ver,1,5,fpt);

     fseek(fpt,0,SEEK_SET);

     fread(ver,1,5,fpt);
     ver[5] = '\0';
     printf("%s",ver);



Hope this time it may help you.
Regards
0
 
LVL 7

Author Comment

by:nsanga
ID: 8015776
Rajeev,
Thanks for the suggestions and the code. I will try this and let you know.

My case is follows

1. As you have mentioned in Step 1

FILE *fpt = fopen("test.dat","w+b");
char ver[] = "4.0.2";
// write some long variables
// write a string
fwrite(ver,1,5,fpt);
// write some other data
fclose(fpt);

2. Now, I need to traverse till the version number and write "4.0.3"

Warm regards,
Narahari Sanga

0
 
LVL 8

Expert Comment

by:ssnkumar
ID: 8016012
I think that's simple if length of version number is fixed.
>I have opened the file in "rwb" mode and read the header till the version number.
If you are sure that you have read till version number and after that you have "4.0.2" (or something like that). Then overwriting that with "4.0.3" must work!
I have got a sample program for you here...Try this (there are two files 1.c and 1.txt, both I have produced below. Do try them and give feedback. I am sure they will work for you):

// file 1.c
#include <stdio.h>

main()
{
    FILE *fp;
    char *str = (char *)malloc(25);
    char c;

    fp = fopen("1.txt", "r+wb");

    bzero(str, 25);
    fscanf(fp, "%s", str);
    fscanf(fp, "%s", str);
    fscanf(fp, "%c", &c);

    fprintf(fp, "4.0.3");

    fclose(fp);

    free(str);
}

The sample text file - 1.txt:

Version number 4.0.2 abcdefg
This is the next line
0
 
LVL 12

Expert Comment

by:rajeev_devin
ID: 8016089
Please explain me if the 'long variables', you have written, is fixed or not. what is its' size. if not is there any delimiter. Then I can try out another code for you.
0
 
LVL 6

Expert Comment

by:Mindphaser
ID: 8016159
rajeev_devin

As ssnkumar already pointed out, we stronlgy discourage the use of email discussions here. Our policy is to keep discussions in this forum, so other askers can profit from it. That's what EE is all about, sharing knowledge and information.

I edited all the places where your email address showed up in this thread ....

** Mindphaser - Community Support Moderator **
0
 
LVL 5

Expert Comment

by:Kocil
ID: 8016518
Ooops, correction AGAIN.
This time it will work. Swear !
Last time I forgot to close the file :)

change(char *fname, char *old, char *new)
{
 static THeader buffer;
 FILE* f=fopen(fname, "rw");
 fread(buffer, sizeof(THeader), 1, f);
 if (memcmp(buffer.version,old,5) == 0) {
    memcpy(buffer.version, new, 5);
    fseek(f,0,SEEK_SET);
    fwrite(buffer, sizeof(THeader), 1, f);
    /* add this */
    fseek(f,0,SEEK_END);
    fclose(f);
 }
}
0
 
LVL 5

Expert Comment

by:Kocil
ID: 8016533
Damn ... BUG again.
I should not answer question near sleep time.

change(char *fname, char *old, char *new)
{
  static THeader buffer;
  FILE* f=fopen(fname, "rwb");
  fread(buffer, sizeof(THeader), 1, f);
  if (memcmp(buffer.version,old,5) == 0) {
    memcpy(buffer.version, new, 5);
    fseek(f,0,SEEK_SET);
    fwrite(buffer, sizeof(THeader), 1, f);
  }
  /* move to here */
  fseek(f,0,SEEK_END);
  fclose(f);
}
0
 
LVL 8

Expert Comment

by:ssnkumar
ID: 8022667
nsanga,
did you try out my sample program? Did it work? Any feedback/comments will help me to analyze furthur if needed....:-)

-Narendra
0
 
LVL 7

Author Comment

by:nsanga
ID: 8023132
Narendar,
I have tried your code. It's not writing "4.0.3" into the file.

rajeev_devin.
We are converting the long variable into an equivalent string and writing into the file.

Kocil,
This approach may not work since we are writing a long variable by converting into a string. Also, the number of bytes is also written into the file. The size of the header doesn't exactly read the header since the size of long variables is written into the file as a part of the header.

Warm regards,
Narahari Sanga
0
 
LVL 12

Expert Comment

by:rajeev_devin
ID: 8023152
untill and unless you don't elaborate on your header information, and size, its' really impossible for me to try out anything. Try to elaborate.

regards
0
 
LVL 5

Accepted Solution

by:
Kocil earned 200 total points
ID: 8023295
Well, ... I though your header is fixed length too :)
but it is wrong after I read this WRITE sequence ...
---------------------------------
FILE *fpt = fopen("test.dat","w+b");
char ver[] = "4.0.2";
// write some long variables
// write a string (**** this may vary in lenght ***)
fwrite(ver,1,5,fpt);
// write some other data
fclose(fpt);

---------------------------------
So this is the posible solution

// define your posible MAX header length
#define MAX_HEADER 1024

/* search the key inside the buffer */
/* return position, or -1 if not found */
/* this is not a fast alogorithm, but it's work */
int memscan(const char *buff, const char* key, int nbuff)
{
   int len = strlen(key);
   for(int pos=0; pos < nbuff-len; pos++) {
      if (memcmp(&buff[pos], key, len) == 0) return pos;
   }
   return -1;
}

change(char *fname, char *old, char *new)
{
 int len, pos;
 static char buffer[MAX_HEADER];
 FILE* f=fopen(fname, "wb");

 len = fread(buffer, 1, sizeof(buffer), f);
 pos = memscan(buffer, old, len);
 if (pos > -1) {
   len = strlength(old); // must be the same
   fseek(f,pos,SEEK_SET);
   fwrite(new, 1, len, f);
 }
 fseek(f,0,SEEK_END);
 fclose(f);
}
0
 
LVL 8

Expert Comment

by:ssnkumar
ID: 8023302
>Narendar, I have tried your code. It's not riting "4.0.3" into the file.

I am surprised! I have tested the program on my system (Linux with gcc) and it's writing 4.0.3.
Is it writing something else or your 1.txt is not getting changed!?
I think the problem is with the file opening only! Try the following open statement:
fp = fopen("1.txt", "r+");

-Narendra
0
 
LVL 7

Author Comment

by:nsanga
ID: 8023613
Narendar,
I have created a sample application in VC to test your code (on WinNT system). I have tried the other file opening mode. The file 1.txt is still not changed.


Kocil,
Thank you so much. IT'S WORKING GREAT.

I have tried your code. (I just made a small change in the method "change"
from FILE* f=fopen(fname, "wb");
to FILE* f=fopen(fname, "r+wb");

Warm regards,
Narahari Sanga
0
 
LVL 7

Author Comment

by:nsanga
ID: 8023632
Thank you Kocil.

Since, the version number is written in the very beginning of the file. I feel, I can definitely go for this solution though this is not very fast as mentioned by Kocil.

Warm regards,
Narahari Sanga
0
 
LVL 5

Expert Comment

by:Kocil
ID: 8040264
You wellcome.
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
Examines three attack vectors, specifically, the different types of malware used in malicious attacks, web application attacks, and finally, network based attacks.  Concludes by examining the means of securing and protecting critical systems and inf…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use switch statements in the C programming language.
Suggested Courses
Course of the Month13 days, 21 hours left to enroll

801 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