简体   繁体   中英

Can't copy value from one double to another and the variables reset to 0

The problem that I have is I am trying to compare 2 numbers. I initialize hGpa as a char '0.0'. when the file is read it gets a gpa value and compares it to hGpa. If it is higher its values is assigned to hGpa. The point of this program is to get the highest GPA. My problem is that the value hGpa is never changed. I'm not sure if I am assigning it incorrectly or if I am placing the variables in the wrong location and they keep getting overwritten. Also I am not to familiar with C so I apologize if it is a stupid mistake. Here is my code

I have already tried making the values global however they just keep resetting to 0.0000.

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>


#define MAXCHAR 1000
int main(void){



  FILE *fp;                 //pointer to file
  char *filename;           //pointer to name of file
  char *fileNames[] = {"CSCI4060U_Lab02_data/1.csv", "CSCI4060U_Lab02_data/2.csv",
                       "CSCI4060U_Lab02_data/3.csv", "CSCI4060U_Lab02_data/4.csv",
                       "CSCI4060U_Lab02_data/5.csv", "CSCI4060U_Lab02_data/6.csv",
                       "CSCI4060U_Lab02_data/7.csv"};
  long fileSize;

  int s = sizeof(fileNames) /sizeof(char*); //array consists of 8 char pointers
                                            //each char consists of 8 bytes in memory
                                            //so you get 64 / 8 = 8;



  for(int i = 0                             ; i < sizeof(fileNames)/sizeof(char*); i++){

    printf("Reading from file #%d: %s\n", i+1, fileNames[i] );
    fp = fopen(fileNames[i],"r");
    if(fp == NULL){
      printf("Could not open file %s",fileNames[i]);
      return 1;
    }
    fileSize = ftell(fp);
    char line[MAXCHAR];

    char hFirst = "";
    char hLast = "";
    char hGpa = "0.0";

    while(fgets(line, MAXCHAR, fp) != NULL){
      //printf("%s\n",line);

      char* first = strtok(line, ",");
      char* last = strtok(NULL, ",");
      char* gpa = strtok(NULL,",");

      printf("current highest: %s, %s, %s\n", hFirst, hLast, hGpa);


      double numGpa = atof(gpa);
      double numHGpa = atof(hGpa);

      printf("gpa read: %f ++++++ gpa current: %f\n",numGpa, numHGpa );

      if(&numGpa > &numHGpa){

        hFirst = first;
        hLast = last;
        hGpa = gpa;
        //printf("after assignment: %s, %s, %s\n", hFirst, hLast, hGpa);
      }



    }
    fclose(fp);

  }

  return 0;
}
    fclose(fp);

The sample file I read through is the following:

Jesse,Jordan,0.65
Charles,Austin,3.23
Peter,Cole,1.57
David,Hamilton,2.73

basically it should enter the if statement 2 times and change the value pointed to by hGpa. Again sorry if I am making any stupid obvious mistakes.

For one time I give the messages produces by the compiler :

pi@raspberrypi:/tmp $ gcc -pedantic -Wall c.c
c.c: In function ‘main’:
c.c:37:19: warning: initialization makes integer from pointer without a cast [-Wint-conversion]
     char hFirst = "";
                   ^~
c.c:38:18: warning: initialization makes integer from pointer without a cast [-Wint-conversion]
     char hLast = "";
                  ^~
c.c:39:17: warning: initialization makes integer from pointer without a cast [-Wint-conversion]
     char hGpa = "0.0";
                 ^~~~~
c.c:48:33: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat=]
       printf("current highest: %s, %s, %s\n", hFirst, hLast, hGpa);
                                 ^
c.c:48:37: warning: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘int’ [-Wformat=]
       printf("current highest: %s, %s, %s\n", hFirst, hLast, hGpa);
                                     ^
c.c:48:41: warning: format ‘%s’ expects argument of type ‘char *’, but argument 4 has type ‘int’ [-Wformat=]
       printf("current highest: %s, %s, %s\n", hFirst, hLast, hGpa);
                                         ^
c.c:52:29: warning: passing argument 1 of ‘atof’ makes pointer from integer without a cast [-Wint-conversion]
       double numHGpa = atof(hGpa);
                             ^~~~
In file included from c.c:2:0:
/usr/include/stdlib.h:105:15: note: expected ‘const char *’ but argument is of type ‘char’
 extern double atof (const char *__nptr)
               ^~~~
c.c:58:16: warning: assignment makes integer from pointer without a cast [-Wint-conversion]
         hFirst = first;
                ^
c.c:59:15: warning: assignment makes integer from pointer without a cast [-Wint-conversion]
         hLast = last;
               ^
c.c:60:14: warning: assignment makes integer from pointer without a cast [-Wint-conversion]
         hGpa = gpa;
              ^
c.c:20:7: warning: unused variable ‘s’ [-Wunused-variable]
   int s = sizeof(fileNames) /sizeof(char*); //array consists of 8 char pointers
       ^
c.c:18:8: warning: variable ‘fileSize’ set but not used [-Wunused-but-set-variable]
   long fileSize;
        ^~~~~~~~
c.c:13:9: warning: unused variable ‘filename’ [-Wunused-variable]
   char *filename;           //pointer to name of file
         ^~~~~~~~
c.c: At top level:
c.c:73:5: warning: data definition has no type or storage class
     fclose(fp);
     ^~~~~~
c.c:73:5: warning: type defaults to ‘int’ in declaration of ‘fclose’ [-Wimplicit-int]
c.c:73:5: warning: parameter names (without types) in function declaration
pi@raspberrypi:/tmp $ 

so

char hFirst = "";
char hLast = "";
char hGpa = "0.0";

can be

char * hFirst = "";
char * hLast = "";
char * hGpa = "0.0";

long fileSize; and fileSize = ftell(fp) can be removed

int s = sizeof(fileNames) /sizeof(char*); can be removed

char *filename; can be removed

the final fclose(fp); must be removed

As you see, just asking for the warnings and looking at them allows to remove a lot of errors in your program


Of course the compiler cannot check the semantic

if(&numGpa > &numHGpa){ is probably not what you want, can be if(numGpa > numHGpa){

If I put

Jesse,Jordan,0.65
Charles,Austin,3.23
Peter,Cole,1.57
David,Hamilton,2.73

in one file and I changes fileNames to only have it, the execution is :

pi@raspberrypi:/tmp $ ./a.out
Reading from file #1: in.csv
current highest: , , 0.0
gpa read: 0.650000 ++++++ gpa current: 0.000000
current highest: Charles, s, n
gpa read: 3.230000 ++++++ gpa current: 0.000000
current highest: Peter, le, 

gpa read: 1.570000 ++++++ gpa current: 0.000000
current highest: David, Hamilton, ton
gpa read: 2.730000 ++++++ gpa current: 0.000000

the names are not the right ones, this is because you do not duplicate the result of strtok when you save them into hFirst, hLast and hGpa while you always read & strtok using line

So one possibility is to change

char * hFirst = "";
char * hLast = "";
char * hGpa = "0.0";
...
hFirst = first;
hLast = last;
hGpa = gpa;

by :

char * hFirst = strdup("");;
char * hLast = strdup("");
char * hGpa = strdup("0.0");
...
free(hFirst);
free(hLast);
free(hGpa);
hFirst = strdup(first);
hLast = strdup(last);
hGpa = strdup(gpa);

I initialize with strdup("") etc because of the printf("current highest: %s, %s, %s\\n", hFirst, hLast, hGpa);

To avoid memory leaks change

fclose(fp);

by

fclose(fp);
free(hFirst);
free(hLast);
free(hGpa);

and the execution is now :

pi@raspberrypi:/tmp $ ./a.out
Reading from file #1: in.csv
current highest: , , 0.0
gpa read: 0.650000 ++++++ gpa current: 0.000000
current highest: Jesse, Jordan, 0.65

gpa read: 3.230000 ++++++ gpa current: 0.650000
current highest: Charles, Austin, 3.23

gpa read: 1.570000 ++++++ gpa current: 3.230000
current highest: Charles, Austin, 3.23

gpa read: 2.730000 ++++++ gpa current: 3.230000

Under valgrind :

pi@raspberrypi:/tmp $ valgrind ./a.out
==5547== Memcheck, a memory error detector
==5547== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==5547== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==5547== Command: ./a.out
==5547== 
Reading from file #1: in.csv
current highest: , , 0.0
gpa read: 0.650000 ++++++ gpa current: 0.000000
current highest: Jesse, Jordan, 0.65

gpa read: 3.230000 ++++++ gpa current: 0.650000
current highest: Charles, Austin, 3.23

gpa read: 1.570000 ++++++ gpa current: 3.230000
current highest: Charles, Austin, 3.23

gpa read: 2.730000 ++++++ gpa current: 3.230000
==5547== 
==5547== HEAP SUMMARY:
==5547==     in use at exit: 0 bytes in 0 blocks
==5547==   total heap usage: 12 allocs, 12 frees, 5,518 bytes allocated
==5547== 
==5547== All heap blocks were freed -- no leaks are possible
==5547== 
==5547== For counts of detected and suppressed errors, rerun with: -v
==5547== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM