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.
Printable View
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.
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.
the professors uses my transaction file so we wouldn't have to worry about adjusting to his needs
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.
This is the new transaction file: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;
}
The data 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
Note that #110 is missing from the data file - because it's added only by the transaction file, through numerous transactions.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
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?
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. :)