Re: Stack with file access?.
From: ritchie (ritchie_s01_at_yahoo.com)
Date: 03/27/04
- Next message: Irrwahn Grausewitz: "Re: how to make program invisible"
- Previous message: jacob navia: "Re: how to make program invisible"
- In reply to: Jens.Toerring_at_physik.fu-berlin.de: "Re: Stack with file access?."
- Next in thread: Jens.Toerring_at_physik.fu-berlin.de: "Re: Stack with file access?."
- Reply: Jens.Toerring_at_physik.fu-berlin.de: "Re: Stack with file access?."
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: 27 Mar 2004 11:44:59 -0800
Jens.Toerring@physik.fu-berlin.de wrote in message news:<c445o0$2doua1$1@uni-berlin.de>...
> ritchie <ritchie_s01@yahoo.com> wrote:
> > I have modified my two functions (below).
>
> > The "writeStack" function now loops the stack, writing each node to
> > file.
> > I think that I have this correct so far?
>
> > The "readStack" function now reads the file and creates a new node for
> > the first record.
> > My question here is, how could I modify my code to get this function
> > to read the entire file, creating a new node for each record?
> > I have tried this a number of ways but I keep ending up with just the
> > first record from the file or else an infinite loop.
>
> > Any suggestions would be great.
>
> > Thanks again to all,
> > Ritchie.
>
> > /*~~~~~~~~~ write / read stack functions ~~~~~~~~~~~~~~*/
> > /* write full stack to file */
> > void writeStack ( NodePtr ptr )
> > {
> > FILE * fPtr; /* file pointer */
> > if ((fPtr = fopen("file.dat", "wb")) == NULL) /*create binary
> > file*/
> > puts("Error?..");
> > else
> > {
> > while ( ptr != NULL ) /* loop to write full stack */
> > {
> > fwrite( ptr, sizeof(*ptr), 1, fPtr); /*write stack */
> > ptr = ptr->nextPtr; /* move to next node */
> > }
> fclose( fPtr); /* close file */
> > }
>
> > /* read file into stack */
> > void readStack ( NodePtr *ptr )
>
> You might think about having the function return the pointer instead
> of passing it a double pointer...
>
> > {
> > Node newPtr = malloc( sizeof( Node ) ); /* create new node for file
> > data*/
>
> You need to check if malloc() did succeed and you allso will need to do
> allocation within the loop.
>
> > FILE *fInPtr; /* file pointer */
> >
> > if ((fInPtr = fopen("orders.dat", "rb")) == NULL)
> ^^^^^^^^^^
>
> You're reading from "orders.dat" here but wrote to "file.dat".
>
> > {
> > fprintf(stderr, "\n\nCannot open %s\n", "file.dat");
> > }
>
> You must return if you can't open the file...
>
> > /* read into new node?*/
> > if( ( fread (newPtr, sizeof(*newPtr), 1, fInPtr)) != 1)
> > printf("error??\n");
> >
> > if (newPtr == NULL)
> > {
> > puts("error....");
> > }
> > else
> > {
> > puts("Details:");
> > printf( "ID: %d \n", newPtr-> stackID);
> > printf( "ID: %d \n", newPtr-> stackName);
> >
> > newPtr->nextPtr = *ptr; /* point to next node ? */
> > *ptr = newPtr;
> > }
> fclose(fInPtr);
> > }
> > /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ END ~~~~~~~~~~~~~~*/
>
> Here's an (untested) version of your read routine - I didn't use your
> NodePtr type because I don't like to hide the pointer-ness of a variable.
> If the function returns NULL (instead of the first element of your
> list) it indicates that either an error happened or that there were
> no elements to be read.
>
> Node *readStack( const char *file_name )
> {
> FILE *fInPtr;
> Node *head;
> Node *new_ptr;
> Node *prev_ptr;
>
> if ( ( fInPtr = fopen( file_name, "rb" ) ) == NULL )
> {
> fprintf( stderr, "Can't open file '%s' for reading\n", file_name );
> return NULL;
> }
>
> if ( ( head = malloc( sizeof *head ) ) == NULL )
> {
> fprintf( stderr, "Running out of memory\n" );
> fclose( fInPtr );
> return NULL;
> }
>
> for ( new_ptr = head;
> fread ( new_ptr, sizeof *new_ptr, 1, fInPtr ) ) == 1;
> new_ptr = new_ptr->NextPtr )
> {
> printf( "ID: %d\n", new_ptr->stackID );
> printf( "ID: %d\n", new_ptr->stackName );
>
> if ( ( new_ptr->nextPtr = malloc( sizeof *new_ptr ) ) == NULL )
> {
> fprintf( stderr, "Running out of memory\n" );
>
> fclose( fInPtr );
>
> while ( head != NULL )
> {
> new_ptr = head;
> head = head->NextPtr;
> free( new_ptr );
> }
>
> return NULL;
> }
>
> prev_ptr = new_ptr; /* needed to get rid of the last, unused element */
> }
>
> fclose( fInPtr );
>
> if ( new_ptr == head ) /* no elements could be read */
> head = NULL;
> else /* last allocated element isn't used */
> prev_ptr->NextPtr = NULL;
>
> free( new_ptr );
>
> return head;
> }
> Regards, Jens
Hi,
Thanks to everyone who has replied to my posts.
As suggested, I have taken out the typedef's for my pointer and it is
much clearer, thanks.
I also read up more on files and now just open the file once, ("ab+"),
in main and pass the file pointer to each function.
I believe this incurs less overhead, rather than opening and closing
the file in each function.
I also wanted to try to modify the file.
I tried a million and one ways, but couldn't get it right.
I have tested this out on another small program with just integers and
it worked fine.
I thought that this would entail something like:
1: point file pointer to BOF
2: create new node to read value into /* is this needed? */
3: Loop/Read file & search for record to be modified
4: If value is found, get new value & update record
Am I correct about this algorithm?
If not, can anybody see where I have gone wrong and maybe point me in
the
right direction?
I have included a very basic (no error checking yet) attempt at this
below. The problem here is, a new node is created and written to
file, but not modifing the
specified file value.
Thanks again for taking the time,
Ritchie
/******************* one of my attempts at this *********************/
struct node{
int stackID;
int stackName;
struct node * nextPtr;
};
typedef struct node Node;
....
/*** update a binary file function ***/
/*** params: pointer to pointer to top of stack ****/
/*** iD: value to update, I/O [binary] file pointer ****/
int updateFile(Node **topPtr, int iD, FILE *fIn )
{
rewind( fIn ); /* rewind the file to BOF for read */
while (!feof(fIn)){ /* loop to EOF */
Node *newPtr = malloc( sizeof( Node ) );/* create new node to read
into */
fread (newPtr, sizeof(*newPtr), 1, fIn );
/* fseek( fIn, 0L, SEEK_CUR ); ???? */
if( newPtr->iNodeID == iD ) /* if value entered is found */
{
puts("Record found");
printf( "Record: %d \n", newPtr->iNodeID ); /* display it */
puts("Enter new value: ");
scanf("%d", &newPtr->iNewVal ); /* get new value */
fwrite( newPtr->iHeight, sizeof(*newPtr), 1, fIn ); /* write new
value */
}
}
return 0;
}
- Next message: Irrwahn Grausewitz: "Re: how to make program invisible"
- Previous message: jacob navia: "Re: how to make program invisible"
- In reply to: Jens.Toerring_at_physik.fu-berlin.de: "Re: Stack with file access?."
- Next in thread: Jens.Toerring_at_physik.fu-berlin.de: "Re: Stack with file access?."
- Reply: Jens.Toerring_at_physik.fu-berlin.de: "Re: Stack with file access?."
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|