File Read Problem

Discussion in 'C' started by docmur, Oct 14, 2007.

  1. docmur

    docmur New Member

    Joined:
    Sep 27, 2007
    Messages:
    3
    Likes Received:
    0
    Trophy Points:
    0
    Okay so I have a file which I put part data into. I then have to read the file, the problem is my code doesn't seem to want to dump the file. I'll post the code and if anyone can help me that would be awesome
    Code:
    /* Create and/or list a random file, which is a parts list with
     * sub-assemblies. Sub-assemblies get expanded as they are listed.
     *
     * Lab 6 - comment this listing, and add the Dump() function.
     */
    
    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
    #include <limits.h>
    
    #define FILENAME            "parts.dat"	// parts database
    #define PART_NAME_LEN       20		// max length of a part name
    #define PART_MAX_COMPONENTS 10      		// at most 10 parts make up an assembly
    
    struct Part {
        int iPartNum;                  // NOTE the same as the record number in the file
        char    szName[PART_NAME_LEN];          // part name
        char    cPartType;                      // 'P' for Part, 'A' for assembly etc
        int     iQuantity;                      // quantity on hand
        int iComponents[PART_MAX_COMPONENTS];   // parts which make up this part, 
         // IF it's an assembly. -1 for unused.
    }parts;
    
    typedef struct Part Part;
    
    int DumpPartsList(int iExplode);
    int AddToFile(void);
    
    int main(int argc, char *argv[])
    {
        if ( argc > 1 ) {
            // file creation mode. Prompt the user for data and append to file.
            AddToFile();
    	// then carry on with the dump.
       }
    
        // Dump the parts list without exploding assemblies.
        DumpPartsList(0);
        printf("-----END of non-exploded list. Press Enter to continue------");
        getc(stdin);
    
        // Dump the parts list WITH exploded assemblies.
        DumpPartsList(1);
        printf("-----END of exploded list. Press Enter to continue------");
        getc(stdin);
        return(0);
    }
    
    // This Function will allow a user to enter parts into the database.
    int AddToFile(void)
    {
        FILE    *fd;
        char    szBuf[80];
        char    *szPtr;
        Part    New;
        int     iRecord;
        int     i, j;
        unsigned int iChars;
    
        // Open a file that will have elements placed into opened as a binary will all attributes given to it 
        fd = fopen( FILENAME, "ab" );
        if ( !fd ) {
            printf("File open failed.\n" );
            return(-1);
        }
    	fseek(fd,0L,SEEK_END);	// Visual needs this!
    
        // Where are we adding? This will be the next record number.
        iRecord = ftell(fd) / sizeof(Part);
    
        // Add new records to the database, until the user says to stop
        for ( ; ; ) {
            // Get rid of any nasty type-ahead, then get a part number. Quit on ^Z
            fflush(stdin);
            printf("\nPart %d: Enter name [19 max, ^Z to stop]: ", iRecord);
            if ( fgets(New.szName, PART_NAME_LEN-1, stdin) == NULL ) break;
    
            // Ignore blank lines. Remove newlines from non-blank lines.
            i = strlen(New.szName);
            if ( i <= 1 ) continue;
            New.szName[i-1] = '\0';
    
            // Start an infusing getline in Cinite loop which will allow the user to input parts
            for ( ; ; ) {
                fflush(stdin);
                printf("Enter type [p or a]:");
                i = scanf( "%c", &New.cPartType );
                // Quit if no character entered. Otherwise, accept only A or P.
                if ( i < 1 ) break;
                New.cPartType = toupper(New.cPartType);
                if ( New.cPartType == 'A' || New.cPartType == 'P' ) break;
            }
    
            // if no part was entered into the database just quit out
            if ( i < 1 ) break;
    
            // Get the starting quantity.  Default to 10. 
            printf("Enter start quantity: ");
            fflush(stdin);
            i = scanf( "%d", &New.iQuantity );
            if ( i < 1 || New.iQuantity < 0 )
                New.iQuantity = 10;
    
            // Initialize the sub-assembly/component list to all empty.
            for ( i=0; i < PART_MAX_COMPONENTS; ++i ) {
                New.iComponents[i] = -1;
            }
    
            // Combine part numbers into an assembly which will be a collection of parts
            if ( New.cPartType == 'A' ) {
                fflush(stdin);
                printf("Enter up to %d component part numbers, with spaces between.\n",
                        PART_MAX_COMPONENTS );
    
                // Get a list of component parts, and fill them in the iComponents array.
                if ( fgets(szBuf,sizeof(szBuf),stdin) != NULL ) {
                    szPtr = szBuf;
                    for ( i=0; i < PART_MAX_COMPONENTS; ++i ) {
                        // %n tells scanf() to report the number of characters processed.
                        j = sscanf(szPtr, "%d%n", &New.iComponents[i], &iChars);
    			   // HERE!!!
                        if ( j > 0 ) szPtr += iChars;
                        else         break;
                    } // end for all components
                }
            } // end assembly
    
            // Set a part numer equal a record.
            New.iPartNum = iRecord;
    
            // if there is an error writting to the file quit the program
            i = fwrite( &New, sizeof(New), 1, fd );
            if ( i != 1 ) {
                printf("Error writing record %d.\n", iRecord );
                break;
            }
    
            //Increment the bigges loop so the user can enter a new part which is a record.
            ++iRecord;
        }
    
        // Close the file. 
        fclose(fd);
        return(0);
    }
    int DumpPartsList(int iExplode)
    {
    //File Pointer will be used for opening file
    FILE    *fd;
    fd=fopen(FILENAME,"rb");
    //if to test for non exploding
    if(iExplode == 0){
    	//Use a loop to run until the end of file has be reached
    	while(!feof(fd)){
    	//Use fread to read the file
    	fread (&parts, sizeof(struct Part), 1, fd);
    	//Check to see if read was succesful
    	//if(ferror(fd) == 1) break;
    	//As long as there are part numbers in the structer print
    	if (parts.iPartNum != 0) {
    		printf("%-6d%-19s%-11c%-6d\n",parts.iPartNum, parts.szName, parts.cPartType, parts.iQuantity);
    	}//end if
    	}//End While
    }//End if
    //Close the file
    fclose(fd);
    return 0;
    }
    
     
    Last edited by a moderator: Oct 15, 2007
  2. DaWei

    DaWei New Member

    Joined:
    Dec 6, 2006
    Messages:
    835
    Likes Received:
    5
    Trophy Points:
    0
    Occupation:
    Semi-retired EE
    Location:
    Texan now in Central NY
    Home Page:
    http://www.daweidesigns.com
    Please put your code in tags, yourself. I ain't yo mama.

    You say your code doesn't seem to want to dump the file. What does that mean? What errors are you getting? If you don't know what errors you are getting, use a debugger, or sprinkle some printf statements around that provide some relevant information. Guessing isn't an effective troubleshooting method.

    On another note: your compiler might clear the input stream with fflush (stdin), but a standards compliant compiler will not. Your program may cease to work with the next compiler version.

    C and C++ are really bad in this regard, though C++ does provide an ignore function. The best way to handle this reliably in C is to repeatedly read characters from the stream until you get a newline or an EOF. Notice, however, that if there is nothing in the stream, this operation will block, and you're screwed. To prevent that happening, use ungetc to put a character back into the steam, and then read until you get a newline or an EOF.
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice