Read/Write to file

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Martin Svensson

    #1

    Read/Write to file

    Hello!

    I need some help/recommendations on how to do the following.
    I have a program that writes an IP address two control numbers and a
    date to file, on one line. It's a basic text file and it looks like this:

    ----- beginning of file -----
    192.168.0.1 0 0 2004-08-01
    192.168.0.2 1 0 2004-08-21
    192.168.0.4 0 1 2004-08-12
    -------- end of file --------

    I know how to write data to a file. But what if I want to change data in
    this file, for instance, on line two I want to change the first control
    number to a 0 instead of a 1. How would I do this?

    Thank you for an honest answer.

    Best regards
    Martin
  • Jens.Toerring@physik.fu-berlin.de

    #2
    Re: Read/Write to file

    Martin Svensson <skydiver@be-openminded.com> wrote:[color=blue]
    > I need some help/recommendations on how to do the following.
    > I have a program that writes an IP address two control numbers and a
    > date to file, on one line. It's a basic text file and it looks like this:[/color]
    [color=blue]
    > ----- beginning of file -----
    > 192.168.0.1 0 0 2004-08-01
    > 192.168.0.2 1 0 2004-08-21
    > 192.168.0.4 0 1 2004-08-12
    > -------- end of file --------[/color]
    [color=blue]
    > I know how to write data to a file. But what if I want to change data in
    > this file, for instance, on line two I want to change the first control
    > number to a 0 instead of a 1. How would I do this?[/color]

    As long as you don't want to insert something into the file but just
    overwrite parts of it it's rather simple, the following should do
    that (assuming the file is names "data.txt" and leaving out all the
    checks you _should_ do):

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

    int main( void )
    {
    FILE *fp = fopen( "data.txt", "rb+" );

    while ( fgetc( fp ) != '\n' ) /* go to start of 2nd line */
    /* empty */ ;
    fseek( fp, 12, SEEK_CUR ); /* go to char to be changed */
    fprintf( fp, "0" );
    fclose( fp );
    return EXIT_SUCCESS;
    }

    What you can't do is inserting more data then are already there, in
    that case you would have to create a new file, copying everything
    you want to keep and interspersed with the changes.

    Regards, Jens
    --
    \ Jens Thoms Toerring ___ Jens.Toerring@p hysik.fu-berlin.de
    \______________ ____________ http://www.toerring.de

    Comment

    • Eric Sosman

      #3
      Re: Read/Write to file

      Martin Svensson wrote:[color=blue]
      > Hello!
      >
      > I need some help/recommendations on how to do the following.
      > I have a program that writes an IP address two control numbers and a
      > date to file, on one line. It's a basic text file and it looks like this:
      >
      > ----- beginning of file -----
      > 192.168.0.1 0 0 2004-08-01
      > 192.168.0.2 1 0 2004-08-21
      > 192.168.0.4 0 1 2004-08-12
      > -------- end of file --------
      >
      > I know how to write data to a file. But what if I want to change data in
      > this file, for instance, on line two I want to change the first control
      > number to a 0 instead of a 1. How would I do this?[/color]

      Open the file for update ("r+" mode), read all the
      data up to but not including the '0' you want to change,
      do an fseek(stream, 0, SEEK_CUR), and then write the '1'.
      (The fseek() looks like a no-op, but you must do a file-
      positioning operation when changing from input to output.)

      *However*, this technique relies on the fact that '0'
      and '1' are the same length. If you wanted to change the
      0 to 12345 (or change 12345 to 0) this wouldn't work because
      all the remaining characters in the file would need to
      "slide over" to accommodate the change in length. Such
      things can be done, but they are not easy. Two other
      possibilities:

      - Instead of trying to update the file "in place,"
      consider reading the old file and writing a new
      one with updated information. Just copy data from
      the old file to the new, but whenever you recognize
      a line that you want to change, write out the new
      version instead of the old. This technique works
      best if you can "batch" many changes together and
      do them all in one pass over the data.

      - If the order of lines in the file is not important,
      you can "replace" a short line with a longer one
      by (1) marking the original as "ignore me" by
      changing its first character to 'x' or something
      else that can't occur in valid data, and (2) writing
      the new version of the line at the end of the file.
      When reading the file in some other program, ignore
      any line that begins with 'x'.

      There are fancier schemes, too, but I can't tell from
      your description whether they'd be worth while.
      [color=blue]
      > Thank you for an honest answer.[/color]

      I always lie.

      --
      Eric.Sosman@sun .com

      Comment

      • Emmanuel Delahaye

        #4
        Re: Read/Write to file

        Martin Svensson wrote on 11/08/04 :[color=blue]
        > I have a program that writes an IP address two control numbers and a date to
        > file, on one line. It's a basic text file and it looks like this:
        >
        > ----- beginning of file -----
        > 192.168.0.1 0 0 2004-08-01
        > 192.168.0.2 1 0 2004-08-21
        > 192.168.0.4 0 1 2004-08-12
        > -------- end of file --------
        >
        > I know how to write data to a file. But what if I want to change data in this
        > file, for instance, on line two I want to change the first control number to
        > a 0 instead of a 1. How would I do this?
        >
        > Thank you for an honest answer.[/color]

        I'm not sure what an 'honest' answer is, but here is mine:

        - The brute force: Use a text editor. Period.

        - The C-force: you need two files. One on read text mode, one on write
        text mode. You read the original, line by line. You check the line and
        copy them unchanged or not according to your will. he line being just
        another array of char, replacing a character by another one is trivial.

        Of course, you need the FILE functions declared in <stdio.h> (fopen(),
        fgets(), fputs(), fclose() etc.).

        Then you can smartly use rename() and remove() to get a new file with
        the old name, and eventually the n-1 version of the file for undo (.bak
        or whatever).

        --
        Emmanuel
        The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html

        "C is a sharp tool"

        Comment

        • Martin Svensson

          #5
          Re: Read/Write to file

          Thank you very much, it worked just fine. I need to figure out what
          method I will use, read from one file and write to another or have the
          whole data in one file and just replace characters. Let's say I have all
          the data in one file. For example a whole IP scoop in the same format as
          my first example. How do I search the file for let's say and IP address
          and find out what line number it's at? And how do I go to that line
          before I'll write data to the file? I can't find such information in the
          man files for fseek or any other file function.

          Help is much appriciated!
          Thank you once again for the great example!

          Martin



          Jens.Toerring@p hysik.fu-berlin.de wrote:[color=blue]
          > Martin Svensson <skydiver@be-openminded.com> wrote:
          >[color=green]
          >>I need some help/recommendations on how to do the following.
          >>I have a program that writes an IP address two control numbers and a
          >>date to file, on one line. It's a basic text file and it looks like this:[/color]
          >
          >[color=green]
          >>----- beginning of file -----
          >>192.168.0.1 0 0 2004-08-01
          >>192.168.0.2 1 0 2004-08-21
          >>192.168.0.4 0 1 2004-08-12
          >>-------- end of file --------[/color]
          >
          >[color=green]
          >>I know how to write data to a file. But what if I want to change data in
          >>this file, for instance, on line two I want to change the first control
          >>number to a 0 instead of a 1. How would I do this?[/color]
          >
          >
          > As long as you don't want to insert something into the file but just
          > overwrite parts of it it's rather simple, the following should do
          > that (assuming the file is names "data.txt" and leaving out all the
          > checks you _should_ do):
          >
          > #include <stdio.h>
          > #include <stdlib.h>
          >
          > int main( void )
          > {
          > FILE *fp = fopen( "data.txt", "rb+" );
          >
          > while ( fgetc( fp ) != '\n' ) /* go to start of 2nd line */
          > /* empty */ ;
          > fseek( fp, 12, SEEK_CUR ); /* go to char to be changed */
          > fprintf( fp, "0" );
          > fclose( fp );
          > return EXIT_SUCCESS;
          > }
          >
          > What you can't do is inserting more data then are already there, in
          > that case you would have to create a new file, copying everything
          > you want to keep and interspersed with the changes.
          >
          > Regards, Jens[/color]

          Comment

          • Jens.Toerring@physik.fu-berlin.de

            #6
            Re: Read/Write to file

            Martin Svensson <skydiver@be-openminded.com> wrote:[color=blue]
            > Thank you very much, it worked just fine. I need to figure out what
            > method I will use, read from one file and write to another or have the
            > whole data in one file and just replace characters. Let's say I have all[/color]

            Well, Eric Sosman pointed out that you can also "insert" into a
            file (but typically it's not trivial and simply writing to a new
            file and then replacing the old one with it tends to be simpler).
            [color=blue]
            > the data in one file. For example a whole IP scoop in the same format as
            > my first example. How do I search the file for let's say and IP address
            > and find out what line number it's at? And how do I go to that line
            > before I'll write data to the file? I can't find such information in the
            > man files for fseek or any other file function.[/color]

            You will probably have to do that manually, i.e. reading in lines,
            counting them and the number of characters in them and use string
            comparison functions to find out if the IP address you're looking
            for is on that line. Assuming no further complications (i.e. lines
            that are longer than the buffer you use for reading in lines) some-
            thing like the following should do the trick (but take care, it's
            completely untested):

            #define MAX_LINE_LEN 4096 /* must be longer than longest input line! */

            int ip_replace( FILE *fp, const char* old_ip, const char *new_ip )
            {
            long cur_pos = 0;
            char buf[ MAX_LINE_LEN ];
            char *where;

            if ( strlen( old_ip ) != strlen( new_ip ) ) /* can we replace? */
            return 1;
            rewind( fp );
            while ( fgets( buf, MAX_LINE_LEN, fp ) != NULL ) {
            if ( ( where = strstr( buf, old_ip ) ) == NULL ) {
            cur_pos += strlen( buf );
            continue;
            }
            if ( fseek( fp, cur_pos + where - buf, SEEK_SET ) != 0 ||
            fprintf( fp, "%s", new_ip ) != 1 )
            break;
            return 0;
            }
            return 1;
            }

            The function returns 0 if the replacement in the file of 'old_ip' by
            'new_ip' was successful and 1 on all kinds of failures. I didn't
            bother with line numbers here, but it's trivial to add a variable
            for the line count and increment it after each successful fgets().

            Regards, Jens
            --
            \ Jens Thoms Toerring ___ Jens.Toerring@p hysik.fu-berlin.de
            \______________ ____________ http://www.toerring.de

            Comment

            Working...