Question

I wrote a program that takes a person's name and their 10 quiz scores from an...

I wrote a program that takes a person's name and their 10 quiz scores from an input file and then prints it to an output file in a slightly different format that also has the average of their quiz scores. Here is an example

INPUT

Mike Johnson 100 45 68 99 34 66 88 99 88 66

OUTPUT

Student Name Quiz Scores Average

Johnson, Mike 100 45 68 99 34 66 88 99 88 66 75.30

It works fine when there is information in the input file. However, when I test run it when the input file is empty, I get an error message saying "stack around the variable 'avg' was corrupted", it exits with a very large negative number like -21475860, and also has a very strange output

Student Name Quiz Scores Average

ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ´àP÷–, ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ´àP÷– 0 0 0 0 0 0 0 0 0 0 0.00

I'm not sure why this is happening. As you can see in my code, I print the column headers ahead of time, and then have a while loop that happens while not at the end of file. I figured if the file is empty then it would immediately evaluate that it's at the end of file so the while loop wouldn't happen. I know it has something to do with the condition of the while loop or the code in the while loop since when I comment it out it out it doesn't happen.

/*
Author: Benjamin Friedman
Course: COMP.1010, Computing I
Date: 05/01/19
*/

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

char *ReadString(FILE *fp, char buffer[], int size);              
char* ExtractName(FILE *fpQuiz,   char whole_name[]);  
void ExtractScores(FILE* fpQuiz, double* pAvg, int quiz_scores[]);

int main(int argc, char *argv[])
{
   /*pointers to quiz.txt (input) and average.txt (output)*/
   FILE* fpQuiz = NULL; FILE* fpAverage = NULL;
  
   /*open files and check for succssful opening*/
   fpQuiz = fopen("quiz.txt", "r");
   if (fpQuiz == NULL) {
       printf("Filed failed to open.\n");
       exit(1);
   }
   fpAverage = fopen("average.txt", "w");
   if (fpAverage == NULL) {
       printf("File failed to open.\n");
       exit(1);
   }

   //Set up column headings
   fprintf(fpAverage, "%-23s", "Student Name");
   fprintf(fpAverage, "%-40s", "Quiz Scores");
   fprintf(fpAverage, "Average\n\n");
  

   double avg;                   //holds average of quiz scores
   int i;                       //counter
   int quiz_scores[10];       //array to hold quiz scores
   char whole_name[20];       //array to hold last name, first name
  
   if (feof(fpQuiz))
   {
       return 0;
   }
   else {
       while (!feof(fpQuiz))
       {
           //Print name to output: Last, First
           fprintf(fpAverage, "%-20s", ExtractName(fpQuiz, whole_name));

           //Print quiz scores and average quiz score to output
           ExtractScores(fpQuiz, &avg, quiz_scores);
           for (i = 0; i < 10; i++)
           {
               fprintf(fpAverage, "%4d", quiz_scores[i]);
           }
           fprintf(fpAverage, "%10.2f\n", avg);
       }
   }
   fclose(fpQuiz);
   fclose(fpAverage);
  

   return 0;
}

/*extract first and last name separately, put them into one string, return the string*/
char* ExtractName(FILE *fpQuiz, char whole_name[])
{
   char first_name[20];
   char last_name[20];
   int i;
   int k;

   //read the first and last name
   ReadString(fpQuiz, first_name, 20);
   ReadString(fpQuiz, last_name, 20);
  
   //put last name into whole name
   for (i = 0; last_name[i] != '\0'; i++)
   {
       whole_name[i] = last_name[i];
   }
  
   //add a comma and space
   whole_name[i] = ',';
   i++;
   whole_name[i] = ' ';
   i++;

   //put first name into whole name
   for (k = 0; first_name[k] != '\0'; i++, k++)
   {
       whole_name[i] = first_name[k];
   }

   //null terminate the whole name array
   whole_name[i] = '\0';
  
   //return the whole name in format: last_name, first_name
   return whole_name;

}

void ExtractScores(FILE* fpQuiz, double* pAvg, int quiz_scores[])
{
  
   int sum_of_quiz_scores = 0;   //sum of the quiz scores
   int noc;                   /*Checks to see if fscanf got an integer. If it didn't
                               that implies there are no more quiz scores left and
                               the input file is at the next line with the next name*/
   int n;                       //temporarily stores the value of each quiz score
   int i;                       //counter
  
   //Get the first quiz score
   noc = fscanf(fpQuiz, "%d", &n);
   //keep adding quiz scores to quiz_scores array as long as they are present
   for (i = 0; noc == 1; i++)
   {
       quiz_scores[i] = n;
       sum_of_quiz_scores += quiz_scores[i];
       noc = fscanf(fpQuiz, "%d", &n);
   }
   //if there were less than 10 quiz scores, assign the rest of the 10 as 0
   while (i < 10)
   {
       quiz_scores[i] = 0;
       i++;
   }
   //get the average of the quiz scores
   *pAvg = sum_of_quiz_scores / (double)10;

}

char *ReadString(FILE * fp, char buffer[], int size)
{
   char c;
   int noc;
   int i = 0;
  
   /*begin scanning for the first string skipping over widespace characters*/
   noc = fscanf(fp, " %c", &c);

   /*if file is empty or storing array is too small to hold null terminator, return NULL*/
   if (noc == EOF || size < 2 ) {
       return NULL;
   }

   /* if we get past the above ifs tatement, that means there is enough room
   in the storage array and the file isn't empty so we can start collecting strings*/

   /*store the first character is storage array*/
   buffer[i] = c;
   i++;

   /*start collecting the rest of the string*/
   noc = fscanf(fp, "%c", &c);
  
   /*while the character is something we want to keep, we're not at EOF, and there's still room
   for the null terminator*/
   while (noc != EOF && i < size - 1 && !isspace(c) ) {
       buffer[i] = c;
       i++;
       noc = fscanf(fp, "%c", &c);
   }

   /*if we get out of the while loops, there are 3 possible cases. EOF, end of string, widespace*/

   if (noc != EOF)
   {
       ungetc(c, fp);
   }
   buffer[i] = '\0';
   return buffer;
}

0 0
Add a comment Improve this question Transcribed image text
Answer #1

The solution to the above question is given below with screenshot of output.

=====================================================

I kept the logic simple and i have tested all outputs.

I have updated the code with a check to see if file is empty or not.

If there is anything else do let me know in comments.

=====================================================

============ CODE TO COPY ===============================

main.c

/*
Author: Benjamin Friedman
Course: COMP.1010, Computing I
Date: 05/01/19
*/

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

char *ReadString(FILE *fp, char buffer[], int size);              
char* ExtractName(FILE *fpQuiz,   char whole_name[]);  
void ExtractScores(FILE* fpQuiz, double* pAvg, int quiz_scores[]);

int main(int argc, char *argv[])
{
   /*pointers to quiz.txt (input) and average.txt (output)*/
   FILE* fpQuiz = NULL; FILE* fpAverage = NULL;
  
   /*open files and check for succssful opening*/
   fpQuiz = fopen("quiz.txt", "r");
   if (fpQuiz == NULL) {
       printf("Filed failed to open.\n");
       exit(1);
   }

   ////////////////////////////////////////////////////////////////////////////
   // Read the first character of file if it is the EOF character, file is empty
   char ch = fgetc( fpQuiz );

   // checking if first char is EOF
   if ( ch == EOF )
   {
       printf("Filed failed to open. file empty\n");
       exit(1);
       fclose(fpQuiz);
   }

   // put the first char back to stream, for normal processing
   ungetc( ch, fpQuiz );
   ////////////////////////////////////////////////////////////////////////////
        

   fpAverage = fopen("average.txt", "w");
   if (fpAverage == NULL) {
       printf("File failed to open.\n");
       exit(1);
   }

   //Set up column headings
   fprintf(fpAverage, "%-23s", "Student Name");
   fprintf(fpAverage, "%-40s", "Quiz Scores");
   fprintf(fpAverage, "Average\n\n");
  

   double avg;                   //holds average of quiz scores
   int i;                       //counter
   int quiz_scores[10];       //array to hold quiz scores
   char whole_name[20];       //array to hold last name, first name
  
   if (feof(fpQuiz))
   {
       return 0;
   }
   else {
       while (!feof(fpQuiz))
       {
           //Print name to output: Last, First
           fprintf(fpAverage, "%-20s", ExtractName(fpQuiz, whole_name));

           //Print quiz scores and average quiz score to output
           ExtractScores(fpQuiz, &avg, quiz_scores);
           for (i = 0; i < 10; i++)
           {
               fprintf(fpAverage, "%4d", quiz_scores[i]);
           }
           fprintf(fpAverage, "%10.2f\n", avg);
       }
   }
   fclose(fpQuiz);
   fclose(fpAverage);
  

   return 0;
}

/*extract first and last name separately, put them into one string, return the string*/
char* ExtractName(FILE *fpQuiz, char whole_name[])
{
   char first_name[20];
   char last_name[20];
   int i;
   int k;

   //read the first and last name
   ReadString(fpQuiz, first_name, 20);
   ReadString(fpQuiz, last_name, 20);
  
   //put last name into whole name
   for (i = 0; last_name[i] != '\0'; i++)
   {
       whole_name[i] = last_name[i];
   }
  
   //add a comma and space
   whole_name[i] = ',';
   i++;
   whole_name[i] = ' ';
   i++;

   //put first name into whole name
   for (k = 0; first_name[k] != '\0'; i++, k++)
   {
       whole_name[i] = first_name[k];
   }

   //null terminate the whole name array
   whole_name[i] = '\0';
  
   //return the whole name in format: last_name, first_name
   return whole_name;

}

void ExtractScores(FILE* fpQuiz, double* pAvg, int quiz_scores[])
{
  
   int sum_of_quiz_scores = 0;   //sum of the quiz scores
   int noc;                   /*Checks to see if fscanf got an integer. If it didn't
                               that implies there are no more quiz scores left and
                               the input file is at the next line with the next name*/
   int n;                       //temporarily stores the value of each quiz score
   int i;                       //counter
  
   //Get the first quiz score
   noc = fscanf(fpQuiz, "%d", &n);
   //keep adding quiz scores to quiz_scores array as long as they are present
   for (i = 0; noc == 1; i++)
   {
       quiz_scores[i] = n;
       sum_of_quiz_scores += quiz_scores[i];
       noc = fscanf(fpQuiz, "%d", &n);
   }
   //if there were less than 10 quiz scores, assign the rest of the 10 as 0
   while (i < 10)
   {
       quiz_scores[i] = 0;
       i++;
   }
   //get the average of the quiz scores
   *pAvg = sum_of_quiz_scores / (double)10;

}

char *ReadString(FILE * fp, char buffer[], int size)
{
   char c;
   int noc;
   int i = 0;
  
   /*begin scanning for the first string skipping over widespace characters*/
   noc = fscanf(fp, " %c", &c);

   /*if file is empty or storing array is too small to hold null terminator, return NULL*/
   if (noc == EOF || size < 2 ) {
       return NULL;
   }

   /* if we get past the above ifs tatement, that means there is enough room
   in the storage array and the file isn't empty so we can start collecting strings*/

   /*store the first character is storage array*/
   buffer[i] = c;
   i++;

   /*start collecting the rest of the string*/
   noc = fscanf(fp, "%c", &c);
  
   /*while the character is something we want to keep, we're not at EOF, and there's still room
   for the null terminator*/
   while (noc != EOF && i < size - 1 && !isspace(c) ) {
       buffer[i] = c;
       i++;
       noc = fscanf(fp, "%c", &c);
   }

   /*if we get out of the while loops, there are 3 possible cases. EOF, end of string, widespace*/

   if (noc != EOF)
   {
       ungetc(c, fp);
   }
   buffer[i] = '\0';
   return buffer;
}


=====================================================
Output :

Add a comment
Know the answer?
Add Answer to:
I wrote a program that takes a person's name and their 10 quiz scores from an...
Your Answer:

Post as a guest

Your Name:

What's your source?

Earn Coins

Coins can be redeemed for fabulous gifts.

Not the answer you're looking for? Ask your own homework help question. Our experts will answer your question WITHIN MINUTES for Free.
Similar Homework Help Questions
  • Modify When executing on the command line having only this program name, the program will accept...

    Modify When executing on the command line having only this program name, the program will accept keyboard input and display such until the user does control+break to exit the program. The new code should within only this case situation “if (argc == 1){ /* no args; copy standard input */” Replace line #20 “filecopy(stdin, stdout);” with your new code. Open read a text file “7NoInputFileResponse.txt” that contains a message “There were no arguments on the command line to be tested...

  • Help with my code: The code is suppose to read a text file and when u...

    Help with my code: The code is suppose to read a text file and when u enter the winning lotto number it suppose to show the winner without the user typing in the other text file please help cause when i enter the number the code just end without displaying the other text file #include <stdio.h> #include <stdlib.h> typedef struct KnightsBallLottoPlayer{ char firstName[20]; char lastName[20]; int numbers[6]; }KBLottoPlayer; int main(){ //Declare Variables FILE *fp; int i,j,n,k; fp = fopen("KnightsBall.in","r"); //...

  • C Language Programming. Using the program below - When executing on the command line only this...

    C Language Programming. Using the program below - When executing on the command line only this program name, the program will accept keyboard input and display such until the user does control+break to exit the program. The new code should within only this case situation “if (argc == 1){ /* no args; copy standard input */” Replace line #20 “filecopy(stdin, stdout);” with new code. Open read a text file “7NoInputFileResponse.txt” that contains a message “There were no arguments on the...

  • Below is a basic implementation of the Linux command "cat". This command is used to print...

    Below is a basic implementation of the Linux command "cat". This command is used to print the contents of a file on the console/terminal window. #include <stdio.h> #include <stdlib.h> int main(int argc, char* argv[]) {FILE *fp; if(2 != argc) {priritf ("Usage: cat <filename>\n"); exit(1);} if ((fp = fopen(argv[1], "r")) == NULL) {fprintf (stderr, "Can't. open input file %s\n", argv[1]); exit (1);} char buffer[256]; while (fgets(X, 256, fp) != NULL) fprintf(Y, "%s", buffer); fclose(Z); return 0;} Which one of the following...

  • -I need to write a program in C to store a list of names (the last...

    -I need to write a program in C to store a list of names (the last name first) and age in parallel arrays , and then later to sort them into alphabetical order, keeping the age with the correct names. - Could you please fix this program for me! #include <stdio.h> #include <stdlib.h> #include <string.h> void data_sort(char name[100],int age[100],int size){     int i = 0;     while (i < size){         int j = i+1;         while (j < size){...

  • Open read a text file “7NoInputFileResponse.txt” that contains a message “There were no arguments on the...

    Open read a text file “7NoInputFileResponse.txt” that contains a message “There were no arguments on the command line to be tested for file open.” Append to the program to output to the text log file a new line starting with day time date followed by the message "SUCCESSFUL". Append that message to a file “7Error_Log_File.txt” . ?newline Remember to be using fprintf using stderr using return using exit statements. Test for file existence, test 7NoInputFileResponse.txt file not null (if null...

  • How would I change the following C code to implement the following functions: CODE: #include <stdio.h>...

    How would I change the following C code to implement the following functions: CODE: #include <stdio.h> #include <stdlib.h> int main(int argc, char * argv[]) { if (argc != 2) printf("Invalid input!\n"); else { FILE * f = fopen (argv[1], "r"); if (f != NULL) { printf("File opened successfully.\n"); char line[256]; while (fgets(line, sizeof(line), f)) { printf("%s", line); } fclose(f); } else { printf("File cannot be opened!"); } } return 0; } QUESTION: Add a function that uses fscanf like this:...

  • create case 4 do Method 1:copy item by item and skip the item you want to...

    create case 4 do Method 1:copy item by item and skip the item you want to delete after you are done, delete the old file and rename the new one to the old name. #include int main(void) { int counter; int choice; FILE *fp; char item[100]; while(1) { printf("Welcome to my shopping list\n\n"); printf("Main Menu:\n"); printf("1. Add to list\n"); printf("2. Print List\n"); printf("3. Delete List\n"); printf("4. Remove an item from the List\n"); printf("5. Exit\n\n"); scanf("%i", &choice); switch(choice) { case 1:...

  • In c programming The Consumer Submits processing requests to the producer by supplying a file name, its location and a character. It also outputs the contents of the file provided by the producer...

    In c programming The Consumer Submits processing requests to the producer by supplying a file name, its location and a character. It also outputs the contents of the file provided by the producer to the standard output. The Producer Accepts multiple consumer requests and processes each request by creating the following four threads. The reader thread will read an input file, one line at a time. It will pass each line of input to the character thread through a queue...

  • I need to make it so this program outputs to an output.txt, the program works fine,...

    I need to make it so this program outputs to an output.txt, the program works fine, just need it to fprintf to output.txt #include <stdio.h> #include <string.h> #include <malloc.h> #define MAX 30 struct treeNode { char names[MAX];    struct treeNode *right; struct treeNode *left; }*node; void searchName(char names[], struct treeNode ** parent, struct treeNode ** location) { struct treeNode * ptr, * tempPtr; if(node == NULL)    { *location = NULL; *parent = NULL; return; } if(strcmp(names, node->names) == 0)...

ADVERTISEMENT
Free Homework Help App
Download From Google Play
Scan Your Homework
to Get Instant Free Answers
Need Online Homework Help?
Ask a Question
Get Answers For Free
Most questions answered within 3 hours.
ADVERTISEMENT
ADVERTISEMENT