Thread: Inventory records

  1. #1
    Registered User
    Join Date
    Oct 2005
    Posts
    63

    Inventory records

    been working on this assignment creating an inventory program that will create 100 empty records, let me input data concerning each tool, enable me to list all tools, delete records for discontinued tools and update any information in the file. I think I'm off to a decent start but for some reason cant get this to compile, can anyone spot my dumb mistake.....thanks.
    Code:
    #include <stdio.h>
    
    /* hardwareData structure definition */
    struct hardwareData {
    	int recordNum;
    	char toolname[20];
        int quantity;
    	double cost;
    
    }; /* end structure hardwareData */
    
    int main()
    {
    	FILE *hfPtr; /* hardware.dat file pointer */
    
    	/* create hardwareData with default information */
    	struct hardwareData hardware = { 0, "", 0,0.0 };
    
    	/* fopen opens file; exits if file cannot be opened */
    	if ((hfPtr = fopen( "hardware.dat", "rb+" )) == NULL ) {
      printf( "File could not be opened.\n" );
    	} /* end if */
    	else{ 
      /* require user to specift record number */
      printf( "Enter record number"
      	"( 1 to 100, 0 to end input)\n" );
      scanf( "%d", &hardware.recordNum );
    
      /* user enters information, which is copied into file */
      while ( hardware.recordNum != 0 ) {
    
      	/* user enters tool name, quantity and cost */
      	printf ( "Enter tool name, quantity, cost\n? " );
    
      	/* set record tool name, quantity and cost */
      	fscanf( stdin, "%s%d%f", hardware.toolname, hardware.quantity, &hardware.cost );
    
        /* seek position in file to user-specified record */
        fseek( hfPtr, ( hardware.recordNum - 1 ) *
        sizeof( struct hardwareData ), SEEK_SET );
    
      	/* write user-specified information in file */
      	fwrite( &hardware, sizeof( struct hardwareData ), 1, hfPtr );
    
      	/* enable user to input another record number */
      	printf( " Enter record number\n?" );
      	scanf( "%d", &hardware.recordNum );
      } /* end while */
    
         fclose( hfPtr ); /* fclose closes file */
    	} /* end else */
    
      return 0; /* indicates successful termination */
    
    }  /* end main */

  2. #2
    Registered User
    Join Date
    Oct 2005
    Posts
    63
    nevermind I found the eror, does this satisfy the requirements as listed above?

  3. #3
    Registered User
    Join Date
    Mar 2005
    Posts
    140
    No, it doesn't satisfy the requirements.

    Seems like a silly question. Do you really need someone to answer that for you?

    can you list all the tools?
    can you delete a tool?
    can you update a tool?

    My guess is you need a menu of some sort, where you give choices to, Add, Update, Delete, or Show All tools.

  4. #4
    Registered User
    Join Date
    Oct 2005
    Posts
    63
    cant I just re-enter that record as balnk and delete or update the tool?

  5. #5
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    I'm not sure I'd want to use the following code:

    Code:
     /* seek position in file to user-specified record */
                fseek( hfPtr, ( hardware.recordNum - 1 ) *
                    sizeof( struct hardwareData ), SEEK_SET );
    
                /* write user-specified information in file */
                fwrite( &hardware, sizeof( struct hardwareData ), 1, hfPtr );
    A scenario... User enters 1 for the record number of the first record BUT enters 98 for the record number of the second input record. Now you have unused space between records 1 and 98. Normally, this space is set to NULL. But if some of this space is NOT set to NULL, when you go to display all records, you may be displaying gibberish from this unused area. Also, this is a waste of storage space.

    You may want to consider reading the records into a linked list or struct array, processsing the records and then writing the records back out to the file from the LL or struct array.

  6. #6
    Registered User
    Join Date
    Oct 2005
    Posts
    63
    I am now moving in a different direction with this, Ive created a menu, and finished the text file but have come up with an error and a few warnings saying:

    error C2065: 'hfPtr' : undeclared identifier
    warning C4047 '=' : 'int ' differs in levels of indirection from 'struct _iobuf *'
    warning C4047: '==' : 'int ' differs in levels of indirection from 'void *'
    warning C4133: 'function' : incompatible types - from 'char [29]' to 'struct _iobuf *'
    warning C4133: 'function' : incompatible types - from 'char [22]' to 'struct _iobuf *'

    does anyone see what I've done wrong and anycoments on this code would be appreciated, thanks
    Code:
    #include <stdio.h>
    
    /* hardwareData structure definition */
    struct hardwareData {
    	int recordNum;
    	char toolname[20];
        int quantity;
    	double cost;
    
    }; /* end structure hardwareData */
    
    /* prototypes */
    int enterChoice( void );
    void textFile( FILE *readPtr );
    void updateRecord( FILE *fPtr );
    void newRecord( FILE *fPtr );
    void deleteRecord( FILE *fPtr );
    
    int main()
    {
       FILE *hfPtr; /* hardware.dat file pointer */
       int choice; /* user choice */
    
        /* fopen opens file; exits if file cannot be opened */
    	if ((hfPtr = fopen( "hardware.dat", "rb+" )) == NULL ) {
    		printf( "File could not be opened.\n" );
    	} /* end if */
    	else {
    
    		/* enable user to specify action */
    		while (( choice = enterChoice()) != 5 ) {
    
    			switch ( choice ) {
    				/* create text file from record */
    			case 1: 
    				textFile( hfPtr );
    				break;
    
    				/* update record */
    			case 2: 
    				updateRecord( hfPtr );
    				break;
    
    				/* create record */
    			case 3:
    				newRecord ( hfPtr );
    				break;
    
    				/* delete existing record */
    			case 4:
    				deleteRecord ( hfPtr );
    				break;
    
    				/* display message if user does not enter valid choice */
    			default:
    				printf( "Incorrect choice\n" );
    				break;
    
    			} /* end switch */
    
    		} /* end while */
    
    		fclose( hfPtr ); /* fclose closes the file */
    
    	} /* end else */
    
    	return 0; /* indicate successful termination */
    
    } /* end main */
    
    /* create formated text for printing */
    void textFile( FILE *readPtr )
    {
    	FILE *writePtr; /* hardware.txt file pointer */
    
    	/* create hardwareData with default information */
        struct hardwareData hardware = { 0, "", 0,0.0 };
    
        /* fopen opens file; exits if file cannot be opened */
    	if ((hfPtr = fopen( "hardware.dat", "rb+" )) == NULL ) {
    		printf( "File could not be opened.\n" );
    	} /* end if */
    	else{ 
    		rewind( readPtr ); /* sets pointer to begining of file */
    		fprintf( "writePtr, %-6s%-10s%-8s%-8s\n",
    			"Record#", "Tool name", "Quantity", "Cost" );
    
    		/* copy all records from random-access file to text file */
    		while ( !feof( readPtr ) ) {
    			fread( &hardware, sizeof( struct hardwareData ),1, readPtr );
    
    			/* write single record to text file */
    			if ( hardware.recordNum != 0 ) {
    				fprintf( "%-6d%-16s%-11d%10.2f\n",
                    hardware.toolname, hardware.quantity, hardware.cost );
    			} /* end if */
    
    		} /* end while */
    
    
        fclose( writePtr ); /* fclose closes file */
    	} /* end else */
    
    } /* end function textrFile */

  7. #7
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Well, undeclared identifier is pretty easy:
    Code:
    /* create formated text for printing */
    void textFile( FILE *readPtr )
    {
    	FILE *writePtr; /* hardware.txt file pointer */
    
    	/* create hardwareData with default information */
        struct hardwareData hardware = { 0, "", 0,0.0 };
    
        /* fopen opens file; exits if file cannot be opened */
    	if ((hfPtr = fopen( "hardware.dat", "rb+" )) == NULL ) {
    		printf( "File could not be opened.\n" );
    	} /* end if */
    	else{
    		rewind( readPtr ); /* sets pointer to begining of file */
    		fprintf( "writePtr, %-6s%-10s%-8s%-8s\n",
    			"Record#", "Tool name", "Quantity", "Cost" );
    
    		/* copy all records from random-access file to text file */
    		while ( !feof( readPtr ) ) {
    			fread( &hardware, sizeof( struct hardwareData ),1, readPtr );
    
    			/* write single record to text file */
    			if ( hardware.recordNum != 0 ) {
    				fprintf( "%-6d%-16s%-11d%10.2f\n",
                    hardware.toolname, hardware.quantity, hardware.cost );
    			} /* end if */
    
    		} /* end while */
    
    
        fclose( writePtr ); /* fclose closes file */
    	} /* end else */
    
    } /* end function textrFile */
    The next one is telling you that the first parameter to fprintf is a FILE* not a string.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  8. #8
    Registered User
    Join Date
    Oct 2005
    Posts
    63
    I dont understand the problem with the undeclared identifier, are they not all declared in the prototypes?

  9. #9
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Where is hfPtr declared in a prototype? Or more to the point, since the name of a parameter in the prototype doesn't matter, where is it declared in the function? (The compiler is asking you the same question.)

    [edit]While we're at it:

    FAQ > Explanations of... > Why it's bad to use feof() to control a loop
    Last edited by Dave_Sinkula; 11-15-2005 at 09:14 PM.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  10. #10
    Registered User
    Join Date
    Oct 2005
    Posts
    63
    I fixed the hfPtr, it was the others that I thought were declared in the prototype. Its now giving me an error that says writePr is being used without having been initialized but I thought that this had initialized it.
    Code:
    /* create formated text for printing */
    void textFile( FILE *readPtr )
    {
    	FILE *writePtr; /* hardware.txt file pointer */
    
    	/* create hardwareData with default information */
        struct hardwareData hardware = { 0, "", 0,0.0 };
    
        /* fopen opens file; exits if file cannot be opened */
    	if ((hfPtr = fopen( "hardware.dat", "rb+" )) == NULL ) {
    		printf( "File could not be opened.\n" );
    	} /* end if */
    	else{ 
    		rewind( readPtr ); /* sets pointer to begining of file */
    		fprintf( writePtr, "%-6s%-10s%-8s%-8s\n",
    			"Record#", "Tool name", "Quantity", "Cost" );
    p.s. feof is what is used in my book so thats why I used it.
    Last edited by jsbeckton; 11-17-2005 at 08:37 AM.

  11. #11
    Registered User
    Join Date
    Oct 2005
    Posts
    63
    Still having that error with the rest of the code completed, anyone have and ideas? It compiles as is but when I try to enter information it must have a continous loop or something?
    Code:
    /* hardwareware.dat */
    
    #include <stdio.h>
    
    /* hardwareData structure definition */
    struct hardwareData {
    	int recordNum;
    	char toolname[20];
        int quantity;
    	double cost;
    
    }; /* end structure hardwareData */
    
    /* prototypes */
    int enterChoice( void );
    void textFile( FILE *readPtr );
    void updateRecord( FILE *fPtr );
    void newRecord( FILE *fPtr );
    void deleteRecord( FILE *fPtr );
    
    FILE *hfPtr; /* hardware.dat file pointer */
    
    int main()
    {
       FILE *hfPtr; /* hardware.dat file pointer */
       int choice; /* user choice */
    
        /* fopen opens file; exits if file cannot be opened */
    	if ((hfPtr = fopen( "hardware.dat", "rb+" )) == NULL ) {
    		printf( "File could not be opened.\n" );
    	} /* end if */
    	else {
    
    		/* enable user to specify action */
    		while (( choice = enterChoice()) != 5 ) {
    
    			switch ( choice ) {
    				/* create text file from record */
    			case 1: 
    				textFile( hfPtr );
    				break;
    
    				/* update record */
    			case 2: 
    				updateRecord( hfPtr );
    				break;
    
    				/* create record */
    			case 3:
    				newRecord ( hfPtr );
    				break;
    
    				/* delete existing record */
    			case 4:
    				deleteRecord ( hfPtr );
    				break;
    
    				/* display message if user does not enter valid choice */
    			default:
    				printf( "Incorrect choice\n" );
    				break;
    
    			} /* end switch */
    
    		} /* end while */
    
    		fclose( hfPtr ); /* fclose closes the file */
    
    	} /* end else */
    
    	return 0; /* indicate successful termination */
    
    } /* end main */
    
    /* create formated text for printing */
    void textFile( FILE *readPtr )
    {
    	FILE *writePtr; /* hardware.txt file pointer */
    
    	/* create hardwareData with default information */
        struct hardwareData hardware = { 0, "", 0,0.0 };
    
        /* fopen opens file; exits if file cannot be opened */
    	if ((hfPtr = fopen( "hardware.txt", "rb+" )) == NULL ) {
    		printf( "File could not be opened.\n" );
    	} /* end if */
    	else{ 
    		rewind( readPtr ); /* sets pointer to begining of file */
    		fprintf( writePtr, "%-6s%-10s%-8s%-8s\n",
    			"Record#", "Tool name", "Quantity", "Cost" );
    
    		/* copy all records from random-access file to text file */
    		while ( !feof( readPtr ) ) {
    			fread( &hardware, sizeof( struct hardwareData ),1, readPtr );
    
    			/* write single record to text file */
    			if ( hardware.recordNum != 0 ) {
    				fprintf( "%-6d%-16s%-11d%10.2f\n",
                    hardware.toolname, hardware.quantity, hardware.cost );
    			} /* end if */
    
    		} /* end while */
    
    
        fclose( writePtr ); /* fclose closes file */
    	} /* end else */
    
    } /* end function textrFile */
    
    /* update record */
    void updateRecord ( FILE *fPtr )
    {
    	int record; /* record number */
    
    	/* create record data with no information */
        struct hardwareData hardware = { 0, "", 0,0.0 };
    
    	/* obtain number of account to update */
    	printf( "Enter record to update (0-100): ");
    	scanf( "%d", &record );
    
    		/* move file pointer to correct record */
    		fseek( fPtr, ( record - 1 ) * sizeof( struct hardwareData ),
    				SEEK_SET );
    
    		/* read record from file */
    		fread( &record, sizeof( struct hardwareData ), 1, fPtr );
    
    		/* display error if record does not exist */
    		if ( hardware.recordNum == 0) {
    			printf( "Record #%d has no information.\n", record );
    		} /* end if */
    		else { /* update record */
    			printf( "Enter new tool name, quantity,cost \n?" );
    			scanf( "%s%d%f", hardware.toolname, hardware.quantity, hardware.cost );
              
    			fseek( fPtr, ( record - 1 ) * sizeof( struct hardwareData ),
    				   SEEK_SET );
    			 /* write updated record over old record */
    			fwrite( &hardware, sizeof( struct hardwareData ), 1, fPtr );
    		}  /* end else */
    
    } /* end function update record */
    
    /* delete an existing record */
    void deleteRecord( FILE *fPtr )
    {
    
    	struct hardwareData hardware; /* stores record read form file */
    	struct hardwareData blankRecord = { 0, "", 0,0.0 }; /* blank record */
    
    	int recordNum; 
    
    	/* obtain number of record to delete */
    	printf( "Enter record number to delete (0-100): " );
    	scanf( "%d", &recordNum );
    
    	/* move file pointer to correct file */
        fseek( fPtr, ( recordNum - 1 ) * sizeof( struct hardwareData ),
    				   SEEK_SET );
    
    	/* read record from file */
    	fread( &hardware, sizeof( struct hardwareData ), 1, fPtr );
        
    	/* display error if record does not exist */
    	if ( hardware.recordNum==0 ) {
    		printf ( "Record %d does not exist.\n", recordNum );
    	} /* end if */
    	else {  /* delete record */
    
    		/* move file pointer to correct record */
            fseek( fPtr, ( recordNum - 1 ) * sizeof( struct hardwareData ),
    				   SEEK_SET );
    
    		/* replace existing record with blank record */
    		fwrite( &blankRecord,
    			sizeof( struct hardwareData ), 1, fPtr );
    	} /* end else */
    
    } /* end function delete record */
    
    /* create and insert record */
    void newRecord( FILE *fPtr )
    {
    	/* create recordData with default information */
        struct hardwareData hardware  = { 0, "", 0,0.0 };
    
    	int recordNum; 
    
    	/* obtain record number to create */
    	printf( "Enter record number to create (1-100) : " );
    	scanf( "%d", &recordNum );
    	
    	/* move file pointer to correct record */
        fseek( fPtr, ( recordNum - 1 ) * sizeof( struct hardwareData ),
    				   SEEK_SET );
    
    	/* read record */
        fread( &hardware, sizeof( struct hardwareData ), 1, fPtr );
    
    	/* display error if record already exists */
    	if ( hardware.recordNum != 0 ) {
    		printf( "Record already exists" );
    	} /* end if */
    	else { /* create record */
    
    		/* user enters toolname, quantity and cost */
    		printf( "Enter tool name, quantity, cost\n" );
    		scanf( "%s%d%f", &hardware.toolname, &hardware.quantity, &hardware.cost );
    
    	/* move file pointer to correct record */
        fseek( fPtr, ( recordNum - 1 ) * sizeof( struct hardwareData ),
    				   SEEK_SET );			
        /* insert record into file */
    		fwrite( &hardware,
    			sizeof( struct hardwareData ), 1, fPtr );
    	} /* end else */
    
    } /* end function newRecord */
    
    /* enable user to input menu choice */
    int enterChoice( void )
    {
    
    	int menuChoice; /* variable to stoer users choice */
    
    	/* display available options */
    	printf( "\nEnter your choice\n"
    		"1 - store a formatted text file of records called\n"
    		"    \"hardware.txt\"for printing\n"
    	    "2 - update a record\n"
    		"3 - add a new record\n"
    		"4 - delete a record\n"
    		"5 - end program\n? " );
    	scanf( "%d", & menuChoice ); /* recieve choice from user */
    
    	return menuChoice;
    
    } /* end function enterChoice */

  12. #12
    Registered User
    Join Date
    Oct 2005
    Posts
    63
    It brings up the menu, lets me enter a choice, since there is currently nothing in the file, I choose 3

    "enter new record number"

    which works fine by bring up the line

    "enter tool name, quantity, cost"

    however when i enter the information and hit enter, the program continously reprints the menu over and over until I close it.

  13. #13
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Your problem is likely that you are using scanf for input. When you enter a number the newline is left in the input buffer. There are better ways to get input, both for numbers and for strings. These are described in the FAQ, as well as clearing the input buffer of such things as a leftover newline.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  14. #14
    Registered User
    Join Date
    Oct 2005
    Posts
    63
    Is it not possible to use scanf to get input for this? I'm just asking because thats how they have been doing it in my book. Would it not be easieer to fix this rather than redo all of the input functions?

  15. #15
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Just zoomin' through that FAQ, huh?

    FAQ > How do I... (Level 2) > Flush the input buffer
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 26
    Last Post: 07-05-2010, 10:43 AM
  2. reading a file into a block
    By mickey0 in forum C++ Programming
    Replies: 19
    Last Post: 05-03-2008, 05:53 AM
  3. Replies: 26
    Last Post: 06-15-2005, 02:38 PM
  4. Counting number from a random file
    By kamisama in forum C Programming
    Replies: 42
    Last Post: 02-22-2005, 05:16 PM
  5. display records held in a struct
    By colinuk in forum C Programming
    Replies: 3
    Last Post: 02-02-2005, 07:51 AM