Go4Expert

Go4Expert (http://www.go4expert.com/)
-   C (http://www.go4expert.com/forums/c/)
-   -   File Read Problem (http://www.go4expert.com/forums/file-read-problem-t6833/)

docmur 15Oct2007 03:37

File Read Problem
 
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;
}


DaWei 15Oct2007 07:37

Re: File Read Problem
 
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.


All times are GMT +5.5. The time now is 08:31.