Thread: Inventory records

  1. #16
    Registered User
    Join Date
    Oct 2005
    Posts
    63
    I read about that and I cant really understand how else to do it without doing it all over, as far as I can tell it says that scanf is not how a "senior programmer" would collect information from the user. I didn't know what a compiler was 9 weeks ago, this is my first and last programming class as I am an engineering major, I am doing things how they are dfone in the book as I am taking this class online so I have no other sorces, and its a struggle doing this as is without doing something that isn't in my text, I just want to find out why this program is not functioning properly, I know that it can work, I just need to find the problems and now I reworked the create file function a bit and now am down to one warning:

    (98) : warning C4133: 'function' : incompatible types - from 'char [22]' to 'struct _iobuf *'

    It will execute but crashes and gives a error window that says debug assertation failed? I have no idea what this means any help?, heres the updated code
    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 = NULL; /* 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 piece; 
    
    	/* obtain record number to create */
    	printf( "Enter record number to create (1-100) : " );
    	scanf( "%d", &piece);
    	
    	/* move file pointer to correct record */
        fseek( fPtr,  piece  * sizeof( struct hardwareData ),
    				   SEEK_SET );
    
    	/* read record */
        fread( &hardware, sizeof( struct hardwareData ), 1, fPtr );
    
    	/* display error if record already exists */
    	if ( !hardware.recordNum ) {  /* create record */
    		hardware.recordNum = piece;
    		printf( "Enter tool name, quantity, cost\n?" );
            scanf(" %[^0-9] %d%f", hardware.toolname, &hardware.quantity,
    			&hardware.cost);
    
          /* move file pointer to correct record */
    		fseek(hfPtr, hardware.recordNum * sizeof( struct hardwareData), SEEK_SET);
    
          /* insert record into file */
    		fwrite( &hardware, sizeof( struct hardwareData), 1, hfPtr);
    	} /* end if */
    	else { 
          /* user enters toolname, quantity and cost */
    		printf( "Record already exists.\n" );
    	} /* 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 */

  2. #17
    Registered User
    Join Date
    Mar 2005
    Posts
    140
    Remove this global variable, and you'll see you are often using the wrong file pointer. That's a big part of your errors. You should not need this global at all (above main)
    Code:
    FILE *hfPtr; /* hardware.dat file pointer */
    in textFile you're missing writePtr as the first paramter to your second fprintf

    in updateRecord you pass &record to fread, you should be passing &hardware

    another large bug is you are inconsitent when subtracting 1 from record when doing your fseek calls. either always do it or never do it.

    make your scanf's consistent when reading data (add and update). You'll notice your are missing some &'s in your update routine. for simplicity why not just
    Code:
    scanf( "%s %d %f", hardware.toolname, &hardware.quantity, &hardware.cost );
    Ideally you'd handle this better but it's a start


    I don't understand what you are trying to do with textFile.
    do you realize it's a different filename .txt vs .dat?
    Edit. Ah i see... just creating a human readable version of the data


    Actually seems like you're pretty close.
    How about an option to show all the tools. Just write a loop that checks all 100 possible spots and if recordnum is not zero print the contents
    Last edited by spydoor; 11-18-2005 at 02:41 PM.

  3. #18
    Registered User
    Join Date
    Oct 2005
    Posts
    63
    Thanks for the tips, Ive made some changes, however the underlying problem still remains. It will compile with one warning which I can't seem to figure out:

    (101) : warning C4133: 'function' : incompatible types - from 'char [10]' to 'struct _iobuf *'

    It brings up the menu, lets me choose 3 to add new tool, but when I input the information and pres enter, It prints the menu and says incorrect choice, over and over and over until I manually close the program, any Ideas about the warning or the crash? Thanks for all of your help.


    I thought that I had figured out that warning by adding record.Num to that fprintf command but then recieved the following errors:

    (101) : warning C4133: 'function' : incompatible types - from 'char [9]' to 'struct _iobuf *'
    (102) : warning C4047: 'function' : 'const char *' differs in levels of indirection from 'int '
    (102) : warning C4024: 'fprintf' : different types for formal and actual parameter 2

    Code:
    		/* 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( "%d%s%d%f",
    					hardware.recordNum, hardware.toolname, 
    					hardware.quantity, hardware.cost );
    			} /* end if */
    Last edited by jsbeckton; 11-19-2005 at 11:06 AM.

  4. #19
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Code:
    				fprintf( writePtr, "%d%s%d%f",
    					hardware.recordNum, hardware.toolname, 
    					hardware.quantity, hardware.cost );
    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.*

  5. #20
    Registered User
    Join Date
    Oct 2005
    Posts
    63
    Thanks, it now compiles with no errors or warnings but still will not allow me to enter information?

  6. #21
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Sorry, I'm not following too closely (sticking to your book that has left you confused an unable to write this for yourself rather than implementing the suggestions here that make up for the shortcomings in your book and all); I don't suppose you could post your latest code?
    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.*

  7. #22
    Registered User
    Join Date
    Oct 2005
    Posts
    63
    Code:
    /* hardwareware.dat */
    
    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
    #include <stdlib.h>
    
    /* hardwareData structure definition */
    struct hardwareData {
    	int recordNum;
    	char toolname[30];
        int quantity;
    	float 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 = NULL; /* 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 ((writePtr = fopen( "hardware.txt", "r+" )) == 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( writePtr, "%d%s%d%f",
    					hardware.recordNum, 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( &hardware, 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 piece; 
    
    	/* obtain record number to create */
    	printf( "Enter record number to create (1-100) : " );
    	scanf( "%d", &piece);
    	
    	/* move file pointer to correct record */
        fseek( fPtr,  piece  * sizeof( struct hardwareData ),
    				   SEEK_SET );
    
    	/* read record */
        fread( &hardware, sizeof( struct hardwareData ), 1, fPtr );
    
    	/* display error if record already exists */
    	if ( !hardware.recordNum ) {  /* create record */
    		hardware.recordNum = piece;
    		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, hardware.recordNum * sizeof( struct hardwareData), SEEK_SET);
    
          /* insert record into file */
    		fwrite( &hardware, sizeof( struct hardwareData), 1, fPtr);
    	} /* end if */
    	else { 
          /* user enters toolname, quantity and cost */
    		printf( "Record already exists.\n" );
    	} /* 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 */

  8. #23
    Registered User
    Join Date
    Mar 2005
    Posts
    140
    What makes you think records aren't being added. did you look at the .dat file after you tried adding some?

    in both update and delete you do
    Code:
    ( record - 1 ) * sizeof( struct hardwareData )
    but in new you do
    Code:
    hardware.recordNum * sizeof( struct hardwareData) // missing -1 ?
    so if you add at record 1 it will not appear to be there with update or delete because you subtract 1 (so it will look at location zero)... You need to be consistent
    (IMO all 6 of your fseek calls should look exactly the same. Why have a different variable name for your offset in each function? You call it record, recordNum and piece.)


    you shouldn't use feof to control your loop in textFile. I believe your last line will be printed twice if you do it that way. In the board FAQ there is an entry explaining why and alternatives
    Last edited by spydoor; 11-21-2005 at 09:38 AM.

  9. #24
    Registered User
    Join Date
    Apr 2007
    Posts
    2

    Red face

    so..is there any complete code or new successful code for this problem?..

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