I wrote a program that takes in this kind of input:

Short, Sue, , 3.11
Cisneros, Juan, G, 3.67
Andrew, T, 5.67
Superlonglastnamethatdoesnotfit, Betty, Boop, 2
Black, Shirley, T, 4.00

and my program outputs this:

Highest gpa: 4.00
Average gpa: 3.19
Lowest gpa: 2.00

Sue Short 3.11
Juan G. Cisneros 3.67
Betty B. Superlonglastnaemtha 2.00
Shirley T. Black 4.00

and my problem is that the average should be 3.20, not 3.19 because its 3.195. I looked over my code again and I dont think anything is wrong. Do you guys might have an idea why I might be getting this result???

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define TEN 10
#define THREE 3
#define TWENTY 20
#define TEN 10
#define ONE 1
#define FIFTY 50
#define ONE_THOU 1000

typedef struct {
char first_name[TEN+1];
char middle_initial;
char last_name[TWENTY+1];
double users_gpa;
} format_of_file;

int main () {
        /* Declarations: File I/O */
        FILE *inp, *outp;
        double sum,place_temp,min_value,max_value,average_value;
	char place_holder[TWENTY],first_file[FIFTY],second_file[FIFTY],str[ONE_THOU],*ptr;
	format_of_file organized[ONE_THOU];
	int i, count;
	int delimiter_count;
	  
	/* Get users inputs */
	printf("Enter the input file name: ");
	scanf("%s", first_file);
	printf("Enter the output file name: ");
	scanf("%s", second_file);

	inp = fopen(first_file, "r");
	outp = fopen(second_file, "w");

	/* Test if both files for validity */
	if (inp == NULL) {
		perror("Invalid File");
		exit(EXIT_FAILURE);
	}
	if (outp == NULL) {
		perror("Invalid File");
		exit(EXIT_FAILURE);	
	}

  /* Begin Program execution and get each name/gpa until , and then continue */
  count = 0;
  
  while (fgets(str,sizeof(str),inp) != NULL) {

	  delimiter_count = 0;
	  
	  for(i=0; i<strlen(str); i++)
	  {
		  if(str[i]==',')
			  delimiter_count++;
	  }

	  if(delimiter_count==3)
	  {
			/* Get last name */ 
			if ((ptr = strtok(str,", ")) != NULL) {
			  strcpy(organized[count].last_name,ptr);
			  if(strlen(str)>TWENTY)
				  organized[count].last_name[TWENTY]='\0';
			}
			else {
			  organized[count].last_name[0]='\0';
			} 
			/* Get first name */    
			if ((ptr = strtok(NULL,", ")) != NULL) {
			  strcpy(organized[count].first_name,ptr);
			  if(strlen(str)>TEN)
				  organized[count].first_name[TEN]='\0';
			}
			else {
			  organized[count].first_name[0]='\0';
			}
			/* Get Middle or gpa */
			if ((ptr = strtok(NULL,", ")) != NULL ) {
			  /* Checks to see if it is a middle name or double value */
			  strcpy(place_holder,ptr);
			  place_temp = atof(place_holder);	
			  if(place_temp == 0) {
				organized[count].middle_initial=ptr[0];
			  }
			  else {
				/* Convert string to double */
 				  organized[count].users_gpa = atof(ptr);
				organized[count].middle_initial = '\0';
			  }	
			}
			else {
			  organized[count].middle_initial='\0';
			}
			/* Get gpa */
			if ((ptr = strtok(NULL,", ")) != NULL) {
			  /* Convert string to double */
			  organized[count].users_gpa = atof(ptr);
			}
			count++;
	  }
		/* Check to see if the size of the file is under a thousand */
  	if (count > ONE_THOU) {
	    printf("Error with file size\n");
	    return 0;
  	}
	}
	/* Close first File */
         fclose(inp);
	
	/* Find the highest/lowest value/sum and Initialize */
	max_value = organized[0].users_gpa;
	min_value = organized[0].users_gpa;
	sum = 0;
	for (i=0;i < count;i++) {
	  if (max_value < organized[i].users_gpa) {
	    max_value = organized[i].users_gpa;
	  }
	  if (min_value > organized[i].users_gpa) {
	    min_value = organized[i].users_gpa;
	  }
	  sum = sum + organized[i].users_gpa;
	}
	
	/* Find the average value */
	average_value = (sum/count);
  printf("%d\n", count);
  /* Display Results */
  fprintf(outp,"Highest gpa: %.2f\n", max_value);
  fprintf(outp,"Average gpa: %.2f\n", average_value);
  fprintf(outp,"Lowest gpa: %.2f\n\n", min_value);
  
  /* Display Corrected Contents */ 
  for (i=0;i < count;i++) {

    fprintf(outp,"%s", organized[i].first_name);  
	if(organized[i].middle_initial!='\0')
		fprintf(outp," %c.", organized[i].middle_initial);
	fprintf(outp," %s", organized[i].last_name);
    fprintf(outp," %.2f\n", organized[i].users_gpa);

  } 
  fclose(outp);
  
  return 0;
}

You can try rounding up yourself.
Since you want to round up to 2 decimals, the general format I use is:

Number + (10^(-Precision))/2

In your case it is:

-> 3.195 + (10^(-2))/2
-> 3.195 + (0.01)/2
-> 3.195 + (0.005)
-> 3.20

AFAIK printf() will always truncate the least significant value.

Edited 6 Years Ago by nbaztec: n/a

Whoa, I've never seen that before. Thank you very much that was really helpful :)

This question has already been answered. Start a new discussion instead.