.:: Bots United ::.

.:: Bots United ::. (http://forums.bots-united.com/index.php)
-   General Programming (http://forums.bots-united.com/forumdisplay.php?f=25)
-   -   inserting stuff into a file (http://forums.bots-united.com/showthread.php?t=1205)

Cheeseh 29-03-2004 18:35

inserting stuff into a file
 
heyo..

here is what I want to do,

I want to change a line in a ascii file, but it means it will probably make the line longer as I'm adding more characters, the problem with this is the when writing to the file it overwrites it doesn't insert, (you'll know the difference between this if you type with the insert key pressed once :p) so it will eventually overwrite stuff I want to keep after the line, because it is overwriting instead of inserting..

can I do this?

this is what i'm doing atm,..
Code:

if ( linechanged )
{
// fpos = current file position (start of line)
// add i to get the character of the start of the change

        fseek(fp,fPos+i,SEEK_SET);
// print the drive name into the file at this point (as it is missing it,
// this is what I want to insert here)
        fprintf(fp,drive);
        fflush(fp);
// back to the start of the lien, this is inside a loop and
// will check the line again until no more changes need to be done
        fseek(fp,fPos,SEEK_SET);
}


botman 29-03-2004 21:54

Re: inserting stuff into a file
 
You need to open a temporary file, copy the file modifing the line you want to, close the temporary file, delete the file you originally copied, and rename the temporary file to the same name as the file you just deleted.

An alternative is to read the entire file into memory, change the memory image, then write the entire file back out to disk with the same name as the original file.

botman

Pierre-Marie Baty 31-03-2004 07:15

Re: inserting stuff into a file
 
I would rather advise NOT to do this in a temporary file. I'm doing something similar in my bot code ; no matter how you will do it, there's no "insert" function in the standard C libs. You have to read what's BEFORE and AFTER the part you want to change in your file, and then reassemble it together.
Code:

void BotNavSaveBrain (player_t *pPlayer)
{
  // this function saves the navigation nodes in the bot's memory in a file to disk. The
  // authentication being made by comparison of the recorded number of walkfaces, this data
  // is written in the file at the very end of the function, to ensure an error in the save
  // process won't let a badly authenticated file on disk.
  MFILE *mfp;
  FILE *fp;
  bot_brain_t *brain;
  char nav_filename[256];
  char section_name_length;
  navnode_t *node;
  int face_index, link_index, array_index;
  char *section_before = NULL, *section_after = NULL;
  int section_before_size, section_after_start, section_after_size;
  brain = &pPlayer->Bot.BotBrain; // quick access to bot brain
  // build the file name
  sprintf (nav_filename, "racc/knowledge/%s/%s.nav", server.mod_name, NormalizeChars (pPlayer->connection_name));
  // get the section name
  section_name_length = strlen (server.map_name) + 1;
  // open the brain for updating (let's read what's before first)
  mfp = mfopen (nav_filename, "rb");
  if (mfp == NULL)
          TerminateOnError ("BotNavLoadBrain(): Unable to operate on %s's nav brain !\n", pPlayer->connection_name);
  // locate at start of the section to update
  if (mfseekAtSection (mfp, server.map_name) != 0)
          TerminateOnError ("BotNavSaveBrain(): Unable to locate before section to update in %s's nav brain !\n", pPlayer->connection_name);
  section_before_size = mftell (mfp); // get the size of what's before the section to update
  if (section_before_size == 0)
          TerminateOnError ("BotNavSaveBrain(): Unable to read before section to update in %s's nav brain !\n", pPlayer->connection_name);
  section_before = (char *) malloc (section_before_size + 1); // allocate memory for what's before
  if (section_before == NULL)
          TerminateOnError ("BotNavSaveBrain(): malloc() failure for reading before section to update in %s's nav brain !\n", pPlayer->connection_name);
  mfseek (mfp, 0, SEEK_SET); // rewind at start of file
  mfread (section_before, section_before_size, 1, mfp); // and read what's before section to update
  // now locate after the section to update
  if (mfseekAfterSection (mfp, server.map_name) != 0)
  {
          if (section_before != NULL)
                free (section_before); // free the memory we mallocated() for what's before section to update
          TerminateOnError ("BotNavSaveBrain(): Unable to locate after section to update in %s's nav brain !\n", pPlayer->connection_name);
  }
  section_after_start = mftell (mfp); // get the start of what's after the section to update
  mfseek (mfp, 0, SEEK_END);
  section_after_size = mftell (mfp) - section_after_start; // get the size of it
  if (section_after_size > 0)
  {
          section_after = (char *) malloc (section_after_size + 1); // allocate memory for what's after
          if (section_after == NULL)
          {
                if (section_before != NULL)
                        free (section_before); // free the memory we mallocated() for what's before section to update
                TerminateOnError ("BotNavSaveBrain(): malloc() failure for reading after section to update in %s's nav brain !\n", pPlayer->connection_name);
          }
          mfseek (mfp, section_after_start, SEEK_SET); // rewind at where what's after starts
          mfread (section_after, section_after_size, 1, mfp); // and read what's after section to update
  }
  mfclose (mfp); // everything we wanted to know from the previous brain is read, close the file
  // and finally update the brain
  fp = fopen (nav_filename, "wb");
  if (fp == NULL)
  {
          if (section_before != NULL)
                free (section_before); // free the memory we mallocated() for what's before section to update
          if (section_after != NULL)
                free (section_after); // free the memory we mallocated() for what's before section to update
          TerminateOnError ("BotNavSaveBrain(): Unable to operate on %s's nav brain !\n", pPlayer->connection_name);
  }
  fwrite (section_before, section_before_size, 1, fp); // write what's before
  fwrite ("[section]", sizeof ("[section]"), 1, fp); // section tag
  fwrite (server.map_name, section_name_length, 1, fp); // section name
  fwrite ("\0\0\0\0", sizeof (long), 1, fp); // fill the field with zeroes (temporarily)
  // for each navigation node...
  for (face_index = 0; face_index < map.walkfaces_count; face_index++)
  {
          node = &brain->PathMemory[face_index]; // quick access to node
          // write the number of links this node has
          fwrite (&node->links_count, sizeof (char), 1, fp);
          // for each link of this node...
          for (link_index = 0; link_index < node->links_count; link_index++)
          {
                // translate the pointer address into an array relative index
                array_index = ((unsigned long) node->links[link_index].node_from - (unsigned long) brain->PathMemory) / sizeof (navnode_t);
                if ((array_index < 0) || (array_index >= map.walkfaces_count))
                        TerminateOnError ("BotNavSaveBrain(): bad node array index %d (max %d), index %d/%d\n", array_index, map.walkfaces_count - 1, link_index, node->links_count);
                fwrite (&array_index, sizeof (long), 1, fp); // write the walkface index of the link
                // write the reachability type for this link (normal, ladder, elevator...)
                fwrite (&node->links[link_index].reachability, sizeof (short), 1, fp);
                // read the vector origin for this link
                fwrite (&node->links[link_index].v_origin, sizeof (Vector), 1, fp);
          }
  }
  if (section_after_size > 0)
          fwrite (section_after, section_after_size, 1, fp); // and write what's after, if needed
  // now that the map specific data sections have been dumped, we can write the likelevels
  fseek (fp, 0, SEEK_SET); // rewind at start of file
  fseek (fp, sizeof ("RACCNAV"), SEEK_CUR); // skip the "RACCNAV" tag
  fseek (fp, sizeof ("[likelevels]"), SEEK_CUR); // skip the "[likelevels]" tag
  fwrite (&brain->likelevel_ladder, sizeof (long), 1, fp); // write ladder likelevel
  fwrite (&brain->likelevel_falledge, sizeof (long), 1, fp); // write falledge likelevel
  fwrite (&brain->likelevel_elevator, sizeof (long), 1, fp); // write elevator likelevel
  fwrite (&brain->likelevel_platform, sizeof (long), 1, fp); // write platform likelevel
  fwrite (&brain->likelevel_conveyor, sizeof (long), 1, fp); // write conveyor likelevel
  fwrite (&brain->likelevel_train, sizeof (long), 1, fp); // write train likelevel
  fwrite (&brain->likelevel_longjump, sizeof (long), 1, fp); // write train likelevel
  fwrite (&brain->likelevel_swim, sizeof (long), 1, fp); // write the swim likelevel
  fwrite (&brain->likelevel_teleporter, sizeof (long), 1, fp); // write the teleporter likelevel
  // now we're ready to write the authentication tag
  fseek (fp, section_before_size, SEEK_SET); // seek back at start of section
  fseek (fp, sizeof ("[section]"), SEEK_CUR); // skip the [section] tag
  fseek (fp, section_name_length, SEEK_CUR); // skip the section name
  fwrite (&map.walkfaces_count, sizeof (long), 1, fp); // write the # of walkfaces on map
  fclose (fp); // everything is saved, close the file
  if (section_before != NULL)
          free (section_before); // free the memory we mallocated() for what's before section to update
  if (section_after != NULL)
          free (section_after); // free the memory we mallocated() for what's before section to update
  return; // and return
}

I could have formatted all this better somehow, but as usuals I'm lazy.

Cheeseh 02-04-2004 01:02

Re: inserting stuff into a file
 
*whistles at code*

I will return to this sometime, I'm working on about 10 different things at once, not to mention trying pathetically to study aswell. I think the before + change + after will work. Thanks :P


All times are GMT +2. The time now is 14:45.

Powered by vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.