[comp.lang.c] ftell fseek

kim@bilby.cs.uwa.oz.au (Kim Shearer) (12/12/90)

 I have been trying to come to terms with file processing in C.
 After reading the manuals etc... I have still not solved my problem

 What I am trying to do is read %s %d pairs from a file, and update
 the %d part if the %s matches a certain value. To do this I use
 ftell to keep track of where I wish to put the number.
 I realise that if things arn't the same size.... but the big problem is
 this :

    the ftell returns 3 (see example file below) and is stored
    in a long, yet the fseek imediately following resets the
    file to the start. I even read the fine print sating that in
    an update opened file you must seperate in and out operations
    by resets or fseeks.

 If anyone can tell me what is wrong or that this is incorrect use 
 of the "r+" opened file and why, I would be very grateful.

EXAMPLE FILE
-----------------
bob 2
fred 2
-----------------
CODE 
-----------------
#include <stdio.h>

#define MAX_NAMELEN 64

int     my_index, my_ndepts = 0;
FILE    *my_file_p;

main ()
{
   int  dept_no, hours_wrkd, i, old_hours, i_own_it = 0;
   char update_name[MAX_NAMELEN], name[MAX_NAMELEN];
   char filename[MAX_NAMELEN];
   int err_ret;
   long marker;

   sprintf (filename, "department%d", 2);
   my_file_p = fopen (filename, "r+");
   if (my_file_p == NULL) {
      printf (" %d could not open file %s\n", my_index, filename);
      perror (filename);
      exit (0);
   }
   fseek (my_file_p, 0L, 0);
   while (fscanf (my_file_p, "%s", name) == 1) {
      marker = ftell (my_file_p);
      fscanf (my_file_p, "%d", &old_hours);
      if (strcmp ("bob", name) == 0) {
         err_ret = fseek (my_file_p, marker, 0);
         printf (" fseek returns : %d\n", err_ret);
         fprintf (my_file_p[i], " %d", old_hours + hours_wrkd);
         err_ret = fseek (my_file_p, marker, 0);
         fscanf (my_file_p[i], "%d", &old_hours);
      }
   }
}

henry@zoo.toronto.edu (Henry Spencer) (12/13/90)

In article <kim.660990813@kowari> kim@bilby.cs.uwa.oz.au (Kim Shearer) writes:
>         fprintf (my_file_p[i], " %d", old_hours + hours_wrkd);

What is the value of `i', and why on Earth are you subscripting the file
pointer with it?
-- 
"The average pointer, statistically,    |Henry Spencer at U of Toronto Zoology
points somewhere in X." -Hugh Redelmeier| henry@zoo.toronto.edu   utzoo!henry

ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (12/13/90)

In article <kim.660990813@kowari>, kim@bilby.cs.uwa.oz.au (Kim Shearer) writes:
--> while (fscanf (my_file_p, "%s", name) == 1) {
-->     marker = ftell (my_file_p);
>       fscanf (my_file_p, "%d", &old_hours);

There's at least one of your problems.  You're getting the position of
the file JUST AFTER a string.  What you want is the position BEFORE.
In short:

	while (marker = ftell(my_file_p),
	       2 == fscanf(my_file_p, "% s%d", name, &old_hours)
	      ) {
	    /* at this point, fseek()ing back to 'marker' will get
	       you to the point BEFORE the string, so that another
	       fscanf() like the one above will read the right stuff.
	    */
	}

A word of warning:  it would be as well to protect yourself against
overflow.

	char format[80];
	char check;

	sprintf(format, "%%%us%%c%%d", (sizeof name) - 1);

	... 3 == fscanf(my_file_p, format, name, &check, &old_hours)
	    && isspace(check) ...

to read no more characters into name[] than will fit, and check that
reading into name stopped because there was no more of the strig to
read, not because name[] ran out of space.  (The *scanf() functions
are enough to make a C programmer think about getting f2c ...)

-- 
The Marxists have merely _interpreted_ Marxism in various ways;
the point, however, is to _change_ it.		-- R. Hochhuth.