C++/lab 4- last one phewwww (argv)
Expert: Zlatko - 6/2/2010
QuestionHi, I have one final lab due by midnight Friday. I did what I could so far with this one. This time just adding two things to the overall code from before. This time I am to write the data to a binary file with a name passed in with argv. Provide logic to allow the program to open the data file it previously saved and display/add to the data file. These are the two new functions I need to include this time for this lab-
void ReadRecords(STUDENT [], int);
void WriteRecords(STUDENT [], int *, char []);
I appreciate your time and effort helping me. In much appreciation. Shannon
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define _CRT_SECURE_NO_WARNINGS
#define DOS
#ifdef DOS
#define STR_IGNORE_CASE_CMP stricmp
#define FLUSH fflush(stdin)
#else
#define STR_IGNORE_CASE_CMP strcasecmp
#define FLUSH draino();
#endif
void draino(void)
{
char c;
while (( c= fgetc(stdin)) != "
" && c !=EOF);
}
struct student
{
char LastName[20];
char FirstName[15];
float PercentGrade;
char LetterGrade;
};
typedef struct student STUDENT;
void EnterStudents(STUDENT[], int *);
void SortByName(STUDENT [], int );
void SortByGPA(STUDENT[], int );
void WriteToScreen(STUDENT [], int );
void WriteToFile(STUDENT [], int );
void calcPercentGrade(float *); // step 1
void calcLabs(float *);
void calcExams(float *);
void calcFinal(float *);
void calcLetterGrade(float, char *);
#define MSG_PAUSE(x) printf("
%s",x);fflush(stdin); getchar()
#define MAX_STUDENT 3
#define NUMBER_OF_LABS 1
#define NUMBER_OF_EXAMS 1
void ReadRecords(STUDENT [], int);
void WriteRecords(STUDENT [], int *, char []);
main(int argc, char * argv[])//** NOT SURE IF I HAVE EVERYTHING IN MAIN WRITTEN IN OR CORRECT*
{
STUDENT Kiddos[10];
int i;
FILE * fptr;
WriteRecords();
char filename[20];
char name1[10] = "sally";
char name2[10] = "Sally";
char FirstName[10];
char LastName[10];
sprintf(filename,"%s.dat", argv[i]);
ReadRecords(Kiddos, &scount, filename);
// I need an if statement that says if your argc count is not 2 leave the program but I am not sure how to write it.
// argc will have 2 in it- 1 for name of the program, 2 for the 1st argument after the name of the program
if(STR_IGNORE_CASE_CMP(Name1, Name2) == 0)
{
printf("
SAME
");
}
else
{
printf("
NOT SAME
");
}
printf("
Enter Your First Name: ");
scanf("%9s", FirstName);
FLUSH;
printf("
Enter Your Last Name: ");
scanf("%9s", LastName);
FLUSH;
printf("
%s %s", FirstName, LastName);
return(0);
void ReadRecords(Student Kiddos[], int scount)// ** NOT SURE IF I HAVE THIS WRITTEN CORRECTLY!
{
FILE * fptr;
fptr = fopen("%s.dat", "rb");
if(fptr==NULL)
{
printf("
No Records Today!");
fflush(stdin); getchar();
exit(0);
}
i=0;
fread(&Kiddos[i], sizeof(STUDENT), 1, fptr);
while(!feof(fptr))
{
printf("
%s", Kiddos[i].FirstName);
printf("
%s",Kiddos[i].LastName);
i++;
fread(&Kiddos[i], sizeof(STUDENT), 1, fptr);
fclose(fptr);
return;
}
void WriteRecords(Student Kiddos[], int *ptrscount, char name) //// ** NOT SURE IF I HAVE THIS WRITTEN CORRECTLY
{
STUDENT Kiddos[3]= {
{"Shannon", "Miller"},
{"David", "Turnier"},
{"Lady", "GaGa"},
};
FILE * fptr;
int i;
fptr = fopen("%s.dat", "wb");
if(fptr == NULL)
{
printf("
Enter Your First Name: ");
FLUSH;
scanf("%9s", FirstName);
printf("
Enter Your Last Name: ");
FLUSH;
scanf("%9s", LastName);
printf("
%s %s", FirstName, LastName);
exit(0);
}
for(i=0; i<Kiddos; i++)
{
fwrite(&Kiddos[i], sizeof(STUDENT), 1, fptr);
}
fclose(fptr);
return(0);
}
void calcPercentGrade(float *ptrPercentGrade)
{
float Labs;
float Exams;
float Final;
calcLabs(&Labs);
calcExams(&Exams);
calcFinal(&Final);
return;
}
void calcLabs(float *ptrLabs)
{
float Labs = 0;
float oneLab;
int i;
for(i =0; i<NUMBER_OF_LABS; i++)
{
printf("
Enter Lab %d: ", i+1);
fflush(stdin);
scanf("%f", &oneLab);
Labs+=oneLab;
}
return;
}
void calcExams(float *ptrExams)
{
float exams = 0;
float oneExam;
int i;
for(i =0; i<NUMBER_OF_EXAMS; i++)
{
printf("
Enter Exams %d: ", i+1);
fflush(stdin);
scanf("%f", &oneExam);
exams+=oneExam;
}
return;
}
void calcFinal(float *ptrFinal)
{
float Final;
printf("
Enter Final: ");
fflush(stdin);
scanf("%.f", &Final);
Final+=Final;
*ptrFinal= Final *0.20f;
return;
}
void calcLetterGrade(float PercentGrade, char *ptrLetterGrade)
{
*ptrLetterGrade= 'X';
if(PercentGrade > 100 || PercentGrade < 0)
{
*ptrLetterGrade = '*';
}
else
{
if(PercentGrade >= 94)
{
*ptrLetterGrade = 'A';
}
else
{
if(PercentGrade >= 84)
{
*ptrLetterGrade = 'B';
}
else
{
if(PercentGrade >= 74)
{
*ptrLetterGrade= 'C';
}
else
{
if(PercentGrade >= 65)
{
*ptrLetterGrade= 'D';
}
else
{
*ptrLetterGrade = 'F';
}
}
}
}
}
return;
}
void EnterStudents(STUDENT Kiddos[], int *ptrscount)
{
printf("Enter Student's Last Name :");
fflush(stdin);
scanf("%s", Kiddos[*ptrscount].LastName);
while( Kiddos[*ptrscount].LastName[0] != '0')
{
printf("Enter Student's First Name :");
fflush(stdin);
scanf("%s", Kiddos[*ptrscount].FirstName);
calcPercentGrade(&Kiddos[*ptrscount].PercentGrade);
calcLetterGrade(Kiddos[*ptrscount].PercentGrade,&Kiddos[*ptrscount].LetterGrade);
(*ptrscount)++;
printf("Enter Student's Last Name :");
fflush(stdin);
scanf("%s", Kiddos[*ptrscount].LastName);
}
return ;
}
void SortByName(STUDENT Kiddos[], int scount )
{
STUDENT temp;
int i;
int x;
for(x=0; x < scount-1; x++)
{
for(i=0; i <scount-1-x; i++)
{
if(strcmp(Kiddos[i].LastName, Kiddos[i+1].LastName)> 0)
{
temp = Kiddos[i];
Kiddos[i] = Kiddos[i+1];
Kiddos[i+1] = temp;
}
}
}
}
void SortByGPA(STUDENT Kiddos[], int scount )
{
STUDENT temp;
int i;
int x;
for(x=0; x < scount-1; x++)
{
for(i=0; i< scount-1-x ; i++)
{
if( Kiddos[i].PercentGrade < Kiddos[i+1].PercentGrade )
{
temp = Kiddos[i];
Kiddos[i] = Kiddos[i+1];
Kiddos[i+1] = temp;
}
}
}
}
void WriteToScreen(STUDENT Kiddos[], int scount)
{
int i;
for(i=0; i<scount; i++)
{
printf("
%s %c %.2f %c", Kiddos[i].LastName, Kiddos[i].FirstName, Kiddos[i].PercentGrade,Kiddos[i].LetterGrade);
}
printf("
");
}
void WriteToFile(STUDENT Kiddos[], int scount)
{
FILE * fptr;
int i;
fptr = fopen("gradereport.txt", "w");
if( fptr == NULL )
{
printf("
Error Opening File !");
printf("
Press any key to exit program.");
fflush(stdin); getchar();
exit(0);
}
fprintf(fptr, "
G R A D E R E P O R T
");
fprintf(fptr, "Name %% Grade Letter Grade
");
for(i=0; i<scount; i++)
{
fprintf(fptr,"
%s %c %.2f %c", Kiddos[i].LastName, Kiddos[i].FirstName, Kiddos[i].PercentGrade,Kiddos[i].LetterGrade);
fclose(fptr);
}
}
AnswerHello Shannon.
Nice to hear from you again. If I understand correctly, the objective of this last lab is to add read-from-file and write-to-file functions to the last assignment. If so, then eventually the calls to ReadRecords and WriteRecords will be merged into the main menu of the last assignment, right ?
I understand that you are trying to create a test main program to test just the reading and writing functions. That's a good approach. If you are done testing your string compare macros, then you can remove them from the main function. To write your test main, you will need to declare your
STUDENT Kiddos[3]= {
{"Shannon", "Miller"},
{"David", "Turnier"},
{"Lady", "GaGa"},
};
in main, not in WriteRecords. This is so that the test main can call WriteRecords with the parameters that WriteRecords wants.
The test main should call
WriteRecords(Kiddos, 3, "myfilename");
Then it should call the ReadRecords like this
ReadRecords(Kiddos, &kiddoCount, "myfilename");
Ok, what is kiddoCount? It is an integer which ReadRecords will update to tell the main program how many students were found in the file. ReadRecords gets a pointer to the integer so that ReadRecords can update it. WriteRecords does not need a pointer to the count, because WriteRecords does not update the count.
Your ReadRecords function has some problems.
You are not calling fopen correctly. It does not take a %s formatting character. It takes a filename string. Your program should not exit just because the file was not found. It should return back to the main menu, and it should return a value showing that the operation could not be done. You need a closing brace on the while loop.
Your WriteRecords function needs to be told how many kiddos are in the array, and write out that many. There is some code to read a person's name if the file could not be opened. I don't know what the point of that is. Please get rid of it. If the file cannot be opened, the program should print a message, and return to main.
Send me only 3 functions, the main, the ReadRecords, and the WriteRecords, with all the string compare junk removed, and with my corrections added. Do your best. Even if it does not compile, it should at least look like you've read it over to yourself. As you read the program over, ask yourself, for each line
what is the point of the line ?
how does it help the function reach its goal?
If you had done that for WriteRecords, you wouldn't have code that asks for a first name and a last name and the exits just because a file could not be opened. A program should make sense, like a cookbook recipe or a good novel makes sense.
I am looking forward to hearing from you. Please send me your work as an attachment to my email. I find email a better way to communicate.
Best regards
Zlatko