简体   繁体   中英

trying to find the maximum difference between two arrays

edit : Apparently the variable dmax doesn't update with every loop.

I have 2 files that are scanned and inputted into 2 separate arrays but when I run the code to find the daily maximum difference between the same elements of the 2 arrays, the output reaches 107374208.000000. Here is my code down below.

void diff()
{
float ftemp[size], mtemp[size], diff[size], count = 1.0;

feb = fopen("feb.txt", "r");
mar = fopen("mar.txt", "r");

for(i = 1; i < size; i++)
{
    fscanf(feb, "%f", &ftemp[i]);
    fscanf(mar, "%f", &mtemp[i]);

    dmax = (i * 3) - 3;

    if((mtemp[dmax] - ftemp[dmax]) > count && (mtemp[dmax] - ftemp[dmax]) > 0)
    {
        count = mtemp[dmax] - ftemp[dmax];
    }
}

printf("The highest temperature difference between March and February is %f.\n", count);
}

this is the daily temperatures for February

maximum     minimum    average
31.6        22.4        25.9
30.2        22.7        25.5
31.2        22.9        26.1
31.3        23.4        26.4
30.7        23.2        26.2
31.3        23.1        26.4
31.6        23.9        26.4
31.6        24.0        26.9
32.7        24.7        27.5
33.8        24.8        27.7
32.4        25.0        27.6
32.1        24.9        27.6
32.7        25.4        27.9
31.9        25.5        27.6
31.9        25.4        27.8
32.1        25.3        27.8
31.7        25.6        27.8
32.6        25.2        27.7
32.2        24.9        27.5
32.2        24.9        27.7
31.7        25.8        27.7
32.3        25.5        27.9
32.1        24.4        27.3
31.5        24.6        27.2
31.8        24.0        27.0 
32.0        24.4        27.4 
32.4        24.9        27.8
32.1        25.0        27.6

and this is the daily temperatures of March

maximum     minimum    average
32.7        25.1        27.7
33.8        24.8        28.0 
32.9        24.7        27.6
32.9        25.0        27.8
32.9        25.0        27.8
33.0        23.8        27.5
32.6        24.2        27.6
32.8        24.8        27.9
32.0        24.2        27.6
32.3        24.9        27.8
33.6        25.0        28.1
33.4        25.6        28.3
33.8        24.7        28.3
34.1        25.2        28.6
32.7        25.9        28.6
28.2        23.6        25.9
30.7        24.3        26.4
32.7        24.9        27.5
32.5        25.4        27.5
33.6        25.9        27.6
33.1        25.3        27.7
31.0        25.0        27.5
32.8        24.2        27.9
33.0        24.7        28.1
33.2        25.2        28.4
34.0        25.7        28.8
34.4        25.8        29.1
32.7        26.2        28.6
33.3        26.5        28.5
32.3        25.8        28.5
33.0        26.6        28.8    

The code doesn't compile because there's a bunch of undeclared variables like dmax and ftemp .

After fixing that...

  1. The fopen s are unchecked.
  2. The files are assumed to be a certain size.
  3. It's reading well past the initialized portion of the arrays.
  4. fscanf is not checked.
  5. fscanf is a bug generator.

Let's have a look at your loop.

for(i = 1; i < size; i++)
{
    fscanf(feb, "%f", &ftemp[i]);
    fscanf(mar, "%f", &mtemp[i]);

    dmax = (i * 3) - 3;

    if((mtemp[dmax] - ftemp[dmax]) > count && (mtemp[dmax] - ftemp[dmax]) > 0)
    {
        count = mtemp[dmax] - ftemp[dmax];
    }
}

After the first iteration, dmax will always be larger than i (i = 0, dmax = 0; i = 1, dmax = 3; i = 2, dmax = 6). But the loop is only ever populated up to i . So mtemp[dmax] and ftemp[dmax] will never be populated when you try to use them. You'll get garbage.

I suspect you're assuming that fscanf(feb, "%f", &ftemp[i]) is scanning in a whole row of numbers. It's only scanning in one, just like you asked for. To do a whole row, you have to ask for that.

for( int i = 0; i < size; i += 3 ) {
    fscanf(feb, "%f %f %f", &ftemp[i], &ftemp[i+1], &ftemp[i+2]);
    fscanf(mar, "%f %f %f", &mtemp[i], &mtemp[i+1], &mtemp[i+2]);

    ...
}

Note that the loop starts at 0 because arrays start from 0. And it advances by 3, because we're reading in 3 at a time.


This still doesn't work. The first line of your files are all strings, not floating point numbers. fscanf doesn't skip ahead to find a match, if it doesn't match it stops. If you keep trying the same match it will keep trying to read from the same position over and over and over and over again. All your code is doing is trying to read in the first bytes of each file as a floating point number, failing, and then doing it again size times. ftemp[i] and mtemp[i] remain uninitialized so you get garbage.

This is why scanf and fscanf should be avoided. Instead, read in whole lines and process them with sscanf .

The arrays are also unnecessary, you're not doing anything with the previous values, you just need the current min and max.


Taking that all into account, and a few other things, I've rewritten it like this:

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <math.h>
#include <stdlib.h>

/* A little function to open files while checking it was
   successful and giving a good error message if not */
FILE *open_file( const char *file, const char *mode ) {
    FILE *fp = fopen(file, mode);
    if( fp == NULL ) {
        fprintf(
            stderr,
            "Could not open '%s' for '%s': %s\n",
            file, mode, strerror(errno)
        );
        exit(1);
    }

    return fp;
}

/* Instead of using hard coded file names, they're passed in. */
/* Instead of hard coding the use of the diff, it's returned. */
/* I switched to doubles because that's what fabs() returns and
   the extra accuracy can't hurt. */
double largest_max_temp_diff(const char *file1, const char* file2) {
    FILE *feb = open_file(file1, "r");
    FILE *mar = open_file(file2, "r");

    char line1[1024];
    char line2[1024];

    /* Skip the header lines */
    fgets(line1, 1024, feb);
    fgets(line2, 1024, mar);

    double max_diff = 0;

    /* Loop infinitely, loop exit is handled using `break` */
    while(1) {
        /* Read in a line from each file.
           Stop when we reach the end of either file. */
        if( fgets(line1, 1024, feb) == NULL ) {
            break;
        }
        if( fgets(line2, 1024, mar) == NULL ) {
            break;
        }

        /* Read in just the first column, ignore the rest. */
        /* Make sure the parsing was successful. */
        double max1, max2;
        if( sscanf(line1, "%lf %*lf %*lf", &max1) < 1 ) {
            fprintf( stderr, "Could not understand '%s'", line1);
            continue;
        }
        if( sscanf(line2, "%lf %*lf %*lf", &max2) < 1 ) {
            fprintf( stderr, "Could not understand '%s'", line2);
            continue;
        }            

        /* Compare the diffs as absolute values */
        double diff = max2 - max1;
        if(fabs(diff) > fabs(max_diff)) {
            max_diff = diff;
        }
    }

    /* Return the max diff so it can be used as the caller likes */
    return max_diff;
}

int main() {
    /* Get the diff */
    double diff = largest_max_temp_diff("feb.txt", "mar.txt");

    /* Use it */
    printf("The highest temperature difference between March and February is %f.\n", diff);
}

This new code now skips the header lines. It reads a line and parses it separately guaranteeing it won't get stuck. It parses one line at a time using sscanf only storing the max. It checks that the parsing succeeded.

It uses the absolute value to check for the maximum difference, because a difference of -4 is bigger than 3.

Finally, it returns that value for the caller to do what it wants with it. Calculating and printing (or any formatting) in the same function is a red flag; it makes functions inflexible and you wind up writing a lot of duplicate code.

It's not the best code, there's still a lot of duplication, but it's better and it checks itself. When working with files, you always have to check your assumptions.

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