Thread: sequential file program

  1. #76
    Registered User
    Join Date
    May 2008
    Posts
    61
    Man, this is some intense, very thorough coding, which is spectacular.

    It compiles and runs perfectly, as expected from you. Not much more I can say.

  2. #77
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    That function has a lot of specifics just right, works great with the transaction file you gave me, but the logic in it is unable to handle a different transaction file.

    Which I would expect your instructor to have, naturally.

    Glad you got it working now, so you can see it's not full of errors.

    I don't know how long it will take to code up a robust version of that function.

  3. #78
    Registered User
    Join Date
    May 2008
    Posts
    61
    the professors uses my transaction file so we wouldn't have to worry about adjusting to his needs

  4. #79
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    This is an improved version. Same caveats apply, not thoroughly tested - just better.

    This should be used with the transaction file listed below this program, to see the differences.

    Code:
    /*Modifications to a program posted by IneedHelpBad 
    Sequential File Program ver. 0.1
    */
    
    #include <stdio.h>
    #include <string.h>
    
    struct Student {
        int  key;
        char name [7];
        int  test1, test2, test3;
        int  hwCount;
        int  hwPoints;
    } 
    dummy = {-1, "", 0, 0, 0, 0, 0},
    * aStudent;
    
    struct Transaction {
       int type;		
       int key;		
       int value;	
       char name [7];
    };
    
    
    FILE * dataFile, * recordFile,  * transFile; 
    
    int openFiles ( ) {
        if ((dataFile = fopen ("seq_data.txt", "r")) == NULL) {
    	   fprintf (stderr, "Error in opening input file\n");
    	   return 1;
        }
        if ((transFile = fopen ("seq_tran.txt", "r")) == NULL) {
    	   fprintf (stderr, "Error in opening transaction file\n");
    	   return 1;
        }
        if ((recordFile = fopen ("seq_recs.txt", "w+t")) == NULL) {
    	   fprintf (stderr, "Error in opening record file\n");
    	   return 1;
        }
        return 0;
    }
    
    void closeFiles ( ) {
        fclose (dataFile);
        fclose (recordFile);
        fclose(transFile);
    }
    
    struct Student * getOneStudentFromData ( ) {
       struct Student * aStudentPtr;
       int theId, theTest1, theTest2, theTest3, theHwCount, theHwPoints;
       char theName [7];
       char cr;
       fscanf (dataFile, "%d%s%d%d%d%d%d%c",
    	&theId, theName, &theTest1, &theTest2, &theTest3,
    	&theHwCount, &theHwPoints, &cr);
    
       if(theId > -1)   {
          aStudentPtr = (struct Student *) malloc (sizeof (struct Student));
          aStudentPtr->key = theId;
          aStudentPtr->test1 = theTest1;
          aStudentPtr->test2 = theTest2;
          aStudentPtr->test3 = theTest3;
          aStudentPtr->hwCount = theHwCount;
          aStudentPtr->hwPoints = theHwPoints;
          strcpy (aStudentPtr->name, theName);    
       }
       else 
          aStudentPtr = &dummy;
    
       return aStudentPtr;
    }
    struct Transaction * getOneTransFromData ( ) {
       struct Transaction * aTransPtr;
       int Ttype, Tkey, Tvalue;
       char Tname [7] = { '\0' };
       char cr;
       fscanf (transFile, "%d%d%d%s%c", &Ttype, &Tkey, &Tvalue, Tname, &cr);
    
       aTransPtr = (struct Transaction *) malloc (sizeof (struct Transaction));
       aTransPtr->type = Ttype;
       aTransPtr->key = Tkey;
       aTransPtr->value = Tvalue;
       strcpy (aTransPtr->name, Tname);    
       
       return aTransPtr;
    }
    void writeRecord (struct Student * theStudentPtr) {
       fprintf(recordFile, "%d\t%s\t%d\t%d\t%d\t%d\t%d\n", theStudentPtr->key, 
          theStudentPtr->name, theStudentPtr->test1, theStudentPtr->test2, 
          theStudentPtr->test3, theStudentPtr->hwCount, theStudentPtr->hwPoints);    
    }
    int readDataAndWriteRecords (void) {
       int key0, getTrans, getStudent, transSeen, hwcount, hwscore;
       int i, newOne, points, recordsSeen, transError, gar;
       	
       struct Student * theStudentPtr;
       struct Student * newStudentPtr;
       struct Transaction * theTransPtr;
       
       theTransPtr = (struct Transaction *) malloc (sizeof (struct Transaction));
       theStudentPtr = (struct Student *) malloc (sizeof (struct Student));
       newStudentPtr = (struct Student *) malloc (sizeof (struct Student));
    
       recordsSeen = transSeen = transError = newOne = 0;
       getStudent = getTrans = 1;
    
       theStudentPtr = getOneStudentFromData();
       recordsSeen++;
       do {
          if(getTrans == 1)   {
             theTransPtr = getOneTransFromData();
             if(theTransPtr->type < 0)  {
                getTrans = 0;             //get no more transactions
             }
             else
                transSeen++;
          }
    
          if(theTransPtr->key > theStudentPtr->key)  { 
             if(getStudent == 1)
                theStudentPtr = getOneStudentFromData();
                recordsSeen++;
             if(theStudentPtr->key == 0)  {   
                getStudent = 0;
                recordsSeen--;
             }
          }
          if(theStudentPtr->key > 1 && theTransPtr->key < 1)  {
             theStudentPtr = getOneStudentFromData();
             if(theStudentPtr->key > 0)
                recordsSeen++;
             writeRecord(theStudentPtr);
             continue;
          }
          if(theStudentPtr->key < theTransPtr->key)
             writeRecord (theStudentPtr);
          else if(theTransPtr->key < theStudentPtr->key) {
             switch (theTransPtr->type)   {
                case -1: break;
                case 0: 
                   //assign initial values for new record
                   newStudentPtr->key = theTransPtr->key;
                   strcpy(newStudentPtr->name, theTransPtr->name);
                   newStudentPtr->test1 = 0;
                   newStudentPtr->test2 = 0;
                   newStudentPtr->test3 = 0;
                   newStudentPtr->hwCount = 0;
                   newStudentPtr->hwPoints = 0;
                   newOne++;
                   key0 = newStudentPtr->key;
                   while(key0 == newStudentPtr->key)  {
                      theTransPtr = getOneTransFromData();
                      transSeen++;
                      if(key0 != theTransPtr->key)  {
                         getTrans = 0;
                         break;
                      }
                      i = theTransPtr->type;
                      if(i == 1)
                         newStudentPtr->test1 = theTransPtr->value;
                      else if(i == 2)
                         newStudentPtr->test2 = theTransPtr->value;
                      else if(i == 3)
                         newStudentPtr->test3 = theTransPtr->value;
                      if(i > 0 && i < 4)  {
                         if(theTransPtr->value < 0 || theTransPtr->value > 120)  {
                            printf("\n Error: Key %d has a test score out of range, continuing", theTransPtr->key);
                            transError++;
                         }
                      }
                      if(i == 4)  {
                         newStudentPtr->hwCount++;
                         newStudentPtr->hwPoints += theTransPtr->value;
                         if(theTransPtr->value < 0 || theTransPtr->value > 5)  {
                            printf("\n Error: Key %d has a homework point value that is out of range, continuing", theTransPtr->key);
                            transError++;
                         }
                         if(newStudentPtr->hwCount++ < 0 || newStudentPtr->hwCount > 10)  {
                            printf("\n Error: Key %d has a homework count that is out of range, continuing", newStudentPtr->hwCount);
                            transError++;
                         }  
                      }
                      if(i == 5)  {
                         newStudentPtr->hwPoints += theTransPtr->value;
                         points = newStudentPtr->hwPoints;
                         if(points < 0 || points > 50 || points > 5 * newStudentPtr->hwCount)  {
                            printf("\n Error: Key %d has homework points that are out of range, continuing", newStudentPtr->hwPoints);
                            transError++;
                         }
                      }
                   }   //end of while
                   writeRecord(newStudentPtr);
                   break;
                //our student key # is too high - key # synch error
                case 1: case 2: case 3: case 4: case 5:
                   transError++;
                   printf("\n Error: The student key %d and transaction key %d numbers do not match,", theStudentPtr->key, theTransPtr->key);
                   printf("\n        and should. Perhaps a typo in one key number, continuing");
                   writeRecord(theStudentPtr);
                   break;
                default: 
                   printf("\n The first switch case logic, has failed."); 
                   printf("\n Program terminated. Press Enter when Ready");
                   gar = getchar(); gar++;
             }     //end of switch
          }        //end of else if
          else if(theTransPtr->key == theStudentPtr->key) {
             getTrans = 1;
             switch (theTransPtr->type)   {
                case -1: break;
                case 0:
                   transError++;
                   if(strcmp(theTransPtr->name, theStudentPtr->name) == 0)  {
                      printf("\n Error: The record for %s, key # %d, already exists, continuing", 
                      theTransPtr->name, theTransPtr->key);
                   }
                   else
                      printf("\n Error: Key number %d, is already assigned, continuing", theTransPtr->key);
                   break;
                case 1:
                   theStudentPtr->test1 += theTransPtr->value;   
                   if(theStudentPtr->test1 > 120)  {
                      printf("\n Error: Key number %d, has a test one value out of range, continuing", theTransPtr->key);
                      transError++;
                   }
                   break;
                case 2:
                   theStudentPtr->test2 += theTransPtr->value;
                   if(theStudentPtr->test2 > 120)  {
                      printf("\n Error: Key number %d, has a test two value out of range, continuing", theTransPtr->key);
                      transError++;
                   }
                   break;
                case 3:
                   theStudentPtr->test3 += theTransPtr->value;
                   if(theStudentPtr->test3 > 120)  {
                      printf("\n Error: Key number %d, has a test three value out of range, continuing", theTransPtr->key);
                      transError++;
                   }
                   break;
                case 4:
                   theStudentPtr->hwCount++;
                   theStudentPtr->hwPoints += theTransPtr->value;
                   if(theStudentPtr->hwCount < 0 || theStudentPtr->hwCount > 10)  {
                      printf("\n Error: Key number %d has a homework count that is out of range, continuing", theTransPtr->key);
                      transError++;
                   }
                   if(theStudentPtr->hwPoints < 0 || theStudentPtr->hwPoints > 50)  {
                      printf("\n Error: Key number %d has homework points that are out of range, continuing", theTransPtr->key);
                      transError++;
                   }
                   break;
                case 5:
                   theStudentPtr->hwPoints += theTransPtr->value;
                   if(theStudentPtr->hwPoints < 0 || theStudentPtr->hwPoints > 5 * theStudentPtr->hwCount)  {
                      printf("\n Error: Key number %d has homework points that are out of range, continuing", theTransPtr->key);
                      transError++;
                   }
                   break;
                default: 
                   printf("\n The second switch case logic, has failed."); 
                   printf("\n Program terminated. Press Enter when Ready");
                   gar = getchar(); gar++;
             }        //end of switch
             writeRecord (theStudentPtr);
          
          }           //end of else if(key == key)
       } while (theStudentPtr->key != 0);
    
       free(theStudentPtr);
       free(theTransPtr);
       free(newStudentPtr);  
       printf("\n\n %d Transactions were processed, with %d errors", transSeen, transError);
       if(newOne == 1)
          printf("\n %2d New Student was added from the transaction file", newOne);
       else if(newOne > 1)
          printf("\n %2d New Students were added from the transaction file", newOne);
    
       return recordsSeen;
    }
    
    int readRecordsAndPrintData ( ) {
       int total, theKey, theTest1, theTest2, theTest3, theHwCount, theHwPoints;
       int recordsSeen, gar;
       char theName [7] = {'\0'};
       char cr;
       float percent;
       struct Student * myStudentPtr;
       recordsSeen = 0;
       myStudentPtr = (struct Student *) malloc (sizeof (struct Student));
       putchar('\n');
       printf("\n Key\tName\tTotal Points\tPercent of 350 Points\n");
       printf(" =============================================================\n");
       do {
       	fscanf (recordFile, "%d%s%d%d%d%d%d%c", &theKey, theName, &theTest1, 
          &theTest2, &theTest3, &theHwCount, &theHwPoints, &cr);
    
          myStudentPtr->key = theKey;
          myStudentPtr->test1 = theTest1;
          myStudentPtr->test2 = theTest2;
          myStudentPtr->test3 = theTest3;
          myStudentPtr->hwCount = theHwCount;
          myStudentPtr->hwPoints = theHwPoints;
          strcpy (myStudentPtr->name, theName);    
    
          if (myStudentPtr->key != 0) {
             total = 0;
             total = myStudentPtr->test1+myStudentPtr->test2+myStudentPtr->test3;
             if(myStudentPtr->hwPoints > 5 * myStudentPtr->hwCount)
                myStudentPtr->hwPoints = 5 * myStudentPtr->hwCount;
    
             total += myStudentPtr->hwCount + myStudentPtr->hwPoints;
             percent = (total/350.0) * 100;
    
    	      printf (" %d\t%s\t    %d\t\t        %.2f%\n",  myStudentPtr->key,
    		   myStudentPtr->name, total, percent);
    
             recordsSeen++;
    	   }	
       } while (myStudentPtr->key != 0);
    
       free(myStudentPtr);
       return recordsSeen;
    }
    
    int main ( ) {
       int i, numRecords, gar;
    
       for(i = 0; i < 10; i++)
          putchar('\n');
    
       if (openFiles ( )) 
    	   return 1;
        
       numRecords = 0;
       numRecords = readDataAndWriteRecords ( );
       printf ("\n %d records read from data file\n", numRecords);
    
       fseek (recordFile, 0, SEEK_SET);
    
       numRecords = 0;
       numRecords = readRecordsAndPrintData ( );
       printf ("\n %d records read from record file\n", numRecords);
    
       closeFiles ( );
       printf("\n                   Program Complete - Press Enter When Ready\n");
       gar = getchar(); gar++;
       return 0;
    }
    This is the new transaction file:
    Code:
    3	100	5	Jeff	
    4	101	5	Mark	
    1	102	3	Jenn	
    2	103	5	Chris	
    4	104	4	Matt	
    3	105	3	Dan	
    0	106	4	Dave	
    5	107	14	Rich	
    3	108	2	Mike
    1	109	4	Tony	
    0	110	5	Rob	
    2	110	85	Rob
    4	110	1	Rob
    1	110	90	Rob
    3	110	88	Rob
    5	110	5	Rob
    2	111	-4	Sonny	
    3	112	4	Luke	
    4	113	3	April	
    2	114	9	Sheryl	
    4	115	4	Tom	
    5	116	18	Lamont	
    0	117	3	Steve	
    2	118	1	Jake	
    3	119	3	Austin	
    -1	0	0	0
    0	0	0	0
    The data file:
    Code:
    100     Jeff    98 76 86        8       41
    101     Mark    66 51 76        4       31
    102     Jenn    79 89 93        9       44
    103     Chris   44 78 45        3       28
    104     Matt    74 81 88        8       39
    105     Dan     67 91 83        6       24
    106     Dave    55 81 75        7       45
    107     Rich    91 93 89        9       32 
    108     Mike    55 61 78        3       26
    109     Tony    67 68 78        5       45
    111     Sonny   78 81 89        8       15
    112     Luke    91 83 75        8       24
    113     April   66 79 70        6       35
    114     Sheryl  89 81 85        9       50
    115     Tom     79 61 90        5       33
    116     Lamont  80 76 89        7       41
    117     Steve   90 98 100       10      50
    118     Jake    90 78 69        8       25
    219     Austin  91 45 88        7       29
    0       ""      0  0  0         0       0
    Note that #110 is missing from the data file - because it's added only by the transaction file, through numerous transactions.

  5. #80
    Registered User
    Join Date
    May 2008
    Posts
    61
    Don't get me wrong, that is great work and more than I could ever do, but does that kind of situation where the record isn't in the data but in the transactions come up in the assignment?

  6. #81
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Yes, that's a type 0 transaction. It should have "several" duplicate key entries for that key: type 0 to initiate it, then immediately followed by type 1 - 5 to "fill it in".

    "Note to create and populate a new record, you need to use one transaction of type 0, one each of type 1, 2, and 3, and several of type 4."

    You should really add at least one more type 4 for record 110 (the new student), and check that it works OK with that.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. sequential file help plz
    By dutrachr in forum C Programming
    Replies: 4
    Last Post: 04-18-2006, 11:41 AM
  2. Encryption program
    By zeiffelz in forum C Programming
    Replies: 1
    Last Post: 06-15-2005, 03:39 AM
  3. fputs and sequential file
    By sballew in forum C Programming
    Replies: 5
    Last Post: 11-11-2001, 04:48 PM
  4. My program, anyhelp
    By @licomb in forum C Programming
    Replies: 14
    Last Post: 08-14-2001, 10:04 PM