0

I'm trying to get a one dimensional array to equal a specific string from a two dimensional array of strings. I've attached my code and I cannot figure out how to properly use strncpy or strcpy. In my example, I'm trying to get ColdestLake to contain the name of the lake whose yearly average temperature is the coldest. I'm trying to pull this from the array of lake names, Lakes[6][12]. From the math, it should be Lake Superior, so I want "Superior" to become the value of ColdestLake. I am trying to complete the same task with WarmestLake. I have already written the correct code for displaying the temperature. I have attached a photo of the returned value (for this specific code)

Here

I appreciate the time, as I am new to C programming.

Update: Thank you everyone for the help! I am new to C (taking a university class), and unfortunately we learned while(!feof(file)) is what to use, and this is what I have been required to use for this particular project. I have updated my code to ensure that values are not undefined, and have defined 365 as Days. Please let me know if there is anything else I can improve. Thanks!

Code Below:

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <float.h>
#define Days 365

int main ()
{
    //Variable Declaration
    char Lakes[6][12] = {"Superior", "Michigan", "Huron", "Erie", "Ontario", "St. Claire"};
    char ColdestLake[12] = {""};
    char WarmestLake[12] = {""};
    char AboveAverageLakes[6][12] = {"","","","","",""};
    char BelowAverageLakes[6][12] = {"","","","","",""};
    double Sums[7] = {0,0,0,0,0,0,0};
    double Averages[7] = {0,0,0,0,0,0,0};
    double Superior[Days];
    double Michigan[Days];
    double Huron[Days];
    double Erie[Days];
    double Ontario[Days];
    double St_Claire[Days];
    double ColdestTemperature;
    double WarmestTemperature;
    FILE *input;
    int i;
    int j;
    int AboveAverageCount = 0;
    int BelowAverageCount = 0;

    //Initializing The Input Data File
    input = fopen("Lake Data.txt", "r");

    //Assigning Data From File To Array's Of Each Lake
    while (!feof(input))
    {
        for (i = 0; i < 365; i++)
        {
            fscanf(input, "%*lf %*lf %lf %lf %lf %lf %lf %lf", &Superior[i], &Michigan[i], &Huron[i], &Erie[i], &Ontario[i], &St_Claire[i]);
        }
    }

    //Getting Sum Of Each Lake's Temperature
    for (i = 0; i < Days; i++)
    {
        Sums[0] += Superior[i];
        Sums[1] += Michigan[i];
        Sums[2] += Huron[i];
        Sums[3] += Erie[i];
        Sums[4] += Ontario[i];
        Sums[5] += St_Claire[i];

        for (j = 0; j < 6; j++)
        {
            Sums[6] += Sums[j];
        }
    }

    //Getting Average Of Each Lake's Temperature
    Averages[0] = Sums[0]/Days;
    Averages[1] = Sums[1]/Days;
    Averages[2] = Sums[2]/Days;
    Averages[3] = Sums[3]/Days;
    Averages[4] = Sums[4]/Days;
    Averages[5] = Sums[5]/Days;

    //Getting Average Of All Lakes
    for (i = 0; i < 6; i++)
    {
        Averages[6] += Averages[i]/6;
    }

    //Printing Average Of Each Lake's Temperature
    for (i = 0; i < 6; i++)
    {
        printf("The Average For Lake %s Was %.2lf Degrees Celsius.\n",Lakes[i], Averages[i]);
    }


    //Printing The Average Of All The Lakes
    printf("\nThe Average Of All The Lakes Was %.2lf Degrees Celsius.\n", Averages[6]);

    //Calculating Warmest And Coldest Lakes
    ColdestTemperature = DBL_MAX;
    WarmestTemperature = DBL_MIN;

    for (i = 0; i < 6; i++)
    {
        //Getting Coldest Temperature & Lake
        if (Averages[i] < ColdestTemperature)
        {
            ColdestTemperature = Averages[i];
            strcpy(ColdestLake, Lakes[i]);
        }

        //Getting Warmest Temperature & Lake
        if (Averages[i] > WarmestTemperature)
        {
            WarmestTemperature = Averages[i];
            strncpy(WarmestLake, Lakes[i], 12);
        }

        //Counting Lakes Above Average Temperature
        if (Averages[i] > Averages[6])
        {
            AboveAverageCount++;
            strncpy(AboveAverageLakes[i], Lakes[i], 12);
        }

        //Counting Lakes Below Average Temperature
        if (Averages[i] < Averages[6])
        {
            BelowAverageCount++;
            strncpy(BelowAverageLakes[i], Lakes[i], 12);
        }
    }

    //Printing Warmest And Coldest Lakes
    printf("\nThe Coldest Lake Was %s With A Temperature Of %.2lf Degrees Celsius.\n", ColdestLake, ColdestTemperature);
    printf("The Warmest Lake Was %s With A Temperature Of %.2lf Degrees Celsius.\n", WarmestLake, WarmestTemperature);

    //Printing How Many Lakes Are Below Average Temperature
    printf("\nThere Are %d Lakes Below The Average Of All The Lakes. They Are:\n", BelowAverageCount);
    for (i = 0; i < 6; i++)
    {
        if (strcmp(BelowAverageLakes[i],"") == 0)
        {
            continue;
        }
        printf("Lake %s\n", BelowAverageLakes[i]);
    }

    //Printing How Many Lakes Are Above Average Temperature
    printf("\nThere Are %d Lakes Above The Average Of All The Lakes. They Are:\n", AboveAverageCount);
    for (i = 0; i < 6; i++)
    {
        if (strcmp(AboveAverageLakes[i],"") == 0)
        {
            continue;
        }
        printf("Lake %s\n", AboveAverageLakes[i]);
    }
    return(0);
}

JakobAger
  • 1
  • 1
  • 1
    Please replace the image of your output with the output itself, copy-and-pasted as plain text and formatted as code. – Keith Thompson Mar 24 '20 at 01:15
  • BTW, I haven't looked closely at your code but `strncpy` is almost certainly not what you want to use. https://the-flat-trantor-society.blogspot.com/2012/03/no-strncpy-is-not-safer-strcpy.html – Keith Thompson Mar 24 '20 at 01:17
  • Why not `int coldindex, warmindex; for (int i = 0; i < 6; i++) { if (Averages[i] < ColdestTemperature) { ColdestTemperature = Averages[i]; coldindex = i } .. /* same for warm */ }` then you have the index of the warmest and coldest, so your answers are simply `lakes[coldindex]` and `lakes[warmindex]`. – David C. Rankin Mar 24 '20 at 01:52

3 Answers3

1

regarding:

Sums[0] += Superior[i];

and similar statements...

The array Sums[] has not been initialized so this is using uninitialized values as 'source' in a math statement. This results in undefined behavior.

Suggest changing:

double Sums[7],...

to:

double Sums[7] = {0}, ...

OT: for ease of readability and understanding: please follow the axiom: only one statement per line and (at most) one variable declaration per statement.

the posted code contains the 'magic' number 365. 'magic' numbers are numbers with no basis. 'magic' numbers make the code much more difficult to understand, debug, etc. Suggest using a #define or enum statement to give that 'magic' number a meaningful name, then using that meaningful name throughout the code.

Please read: why while(!feof( file ) ) is always wrong

regarding:

Averages[6] += Averages[i]/6;

This is using a source of Averages[6] However that value is never initialized, resulting in undefined behavior. Suggest changing:

 ..., Averages[7],

to:

 ..., Averages[7] = {0},

regarding:

ColdestTemperature = Averages[0];
WarmestTemperature = Averages[0];

for (i = 0; i < 6; i++)
{
    if (Averages[i] < ColdestTemperature)
    {
        ColdestTemperature = Averages[i];
        strcpy(ColdestLake, Lakes[i]);
    }

The above will never update the ColdestLake with "Superior" because Averages will never be less than the initial value of ColdestTemperature Similar considerations for the calculation of the WarmestTemperature.

Suggest replacing:

ColdestTemperature = Averages[0];
WarmestTemperature = Averages[0];

with:

ColdestTemperature = DBL_MAX;
WarmestTemperature = DBL_MIN;

as defined in the header file: limits.h

user3629249
  • 16,402
  • 1
  • 16
  • 17
0

If the coldest lake is Lake Superior, the test if (Averages[i] < ColdestTemperature) will not be true, because you initialized ColdestTemperature to Averages[0]. The simple solution is to also initialize ColdestLake to Lakes[0]. And do similarly for WarmestLake.

And once you've done this, there's no need to check Averages[0] in the loop, so you can start the loop at i = 1.

    //Calculating Warmest And Coldest Lakes
    ColdestTemperature = Averages[0];
    strcpy(ColdestLake, Lakes[0]);
    WarmestTemperature = Averages[0];
    strcpy(WarmestLake, Lakes[0]);

    for (i = 1; i < 6; i++)
    {
        if (Averages[i] < ColdestTemperature)
        {
            ColdestTemperature = Averages[i];
            strcpy(ColdestLake, Lakes[i]);
        }

        if (Averages[i] > WarmestTemperature)
        {
            WarmestTemperature = Averages[i];
            strcpy(WarmestLake, Lakes[i]);
        }
    }
Barmar
  • 741,623
  • 53
  • 500
  • 612
0

As Barmar suggests, the coldestlake is not true because you copyed the first value (which happens to be the coldest) in,so the if cause is never reached,aside from copying the string in first,you can do something like this.

#define INF 0x3f3f3f3f
    ...Your code...
    ColdestTemperature = INF;
    WarmestTemperature = -INF;
    for (i = 0; i < 6; i++)
    {
        if (Averages[i] < ColdestTemperature)
        {
            ColdestTemperature = Averages[i];
            strcpy(ColdestLake, Lakes[i]);
        }

        if (Averages[i] > WarmestTemperature)
        {
            WarmestTemperature = Averages[i];
            strcpy(WarmestLake, Lakes[i]);
        }
    }
xkcdjerry
  • 965
  • 4
  • 15