0

I am reading in a struct from a binary file containing 3 variables Temperature, wind speed and wind direction. I am trying to creating a method of searching for the date stamp written to the file under the variable time_t which is in the form day/month/year. I start by opening the file and reading its items. I then use strcmp to compare a date string entered by the user with the time_t value within the file struct. However, whenever i enter the correct date thus strcmp should return 0, it doesnt return 0. When I enter a value lower than the time_t I do get a strcmp return of -1 and vice versa for a value greater than time_t I get a return of 1, it just wont work when they are equal. Option 2 is where im implementing the Search.

Any advice would be greatly appreciated.

Code:

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

#pragma warning(disable : 4996)

struct readings {
    double temperature;
    double wind_direction;
    double wind_speed;
    time_t time;
};

/*
int compare(const void* a, const void* b)
{
    int search1 = *(int*)a;
    int search2 = *(int*)b;

    if (search1 == search2)
    {
        return 0;
    }
    else if (search1 < search2)
    {
        return -1;
    }
    else if (search1 > search2) {
        return 1;
    }

}*/


int main(void)
{
    struct readings* readings = NULL;
    int option;
    printf_s("Welcome to Data Acquisition Program\n");
    printf_s("Options are as follows:\n 1:Load File\n 2:Search Weather by date\n 3:View Monthly Data\n 4:Export to Excel\n 5:Exit\n");
    printf_s("Enter an option: ");
    scanf_s("%d", &option);

    if (option == 1)
    {

        FILE* pFile;
        errno_t error;
        int num_readings;

        time_t t;
        struct tm* tmp;
        char MY_TIME[50];
        time(&t);


        error = fopen_s(&pFile, "weather.bin", "rb");

        if (error == 0)
        {


            fread(&num_readings, sizeof(int), 1, pFile);
            readings = malloc(sizeof(struct readings) * num_readings);
            fread(readings, sizeof(struct readings), num_readings, pFile);

            for (int i = 0; i < num_readings; i++)
            {
                printf_s("Temperature: %lf\n", readings[i].temperature);
                printf_s("Wind Direction: %lf\n", readings[i].wind_direction);
                printf_s("Wind Speed: %lf\n", readings[i].wind_speed);
                tmp = localtime(&readings[i].time);
                //strftime(MY_TIME, sizeof(MY_TIME), "%x", tmp);
                strftime(MY_TIME, sizeof(MY_TIME), "%x - %I:%M%p", tmp);
            }   printf_s("Date & Time: %s\n", MY_TIME);
            fclose(pFile);
        }
        else { printf_s("Error: %d", error); }
    }



    if (option == 2)
    {
        //searching in file
        //int* result = 0;
        char date[20];

        FILE* pFile;
        errno_t error;
        int num_readings;

        time_t t;
        struct tm* tmp;
        char MY_TIME[50];
        time(&t);

        error = fopen_s(&pFile, "weather.bin", "rb");

        fread(&num_readings, sizeof(int), 1, pFile);
        readings = malloc(sizeof(struct readings) * num_readings);
        fread(readings, sizeof(struct readings), num_readings, pFile);

        if (readings != NULL)
        {

            for (int i = 0; i < num_readings; i++)
            {
                tmp = localtime(&readings[i].time);
                strftime(MY_TIME, sizeof(MY_TIME), "%x", tmp);
                printf_s("Date & Time: %s\n", MY_TIME);
            }

            getchar();
            printf_s("Enter the Date you wish to search for in the form month/day/year: \n");
            fgets(date, sizeof(int), stdin);

            int result;

            // comparing strings str1 and str2
            result = strcmp(date, MY_TIME);
            printf("strcmp = %d\n", result); //returns 0 if equal

            //result = (int*)bsearch(&date, readings, num_readings, sizeof(struct readings), compare);
            //returns NULL if not equal and returns 1 if equal

            if (result == 0)
            {
                printf_s("Date found!\n %d\n", date);
                for (int i = 0; i < num_readings; i++)
                {
                    printf_s("Temperature is: %lf", readings[i].temperature);
                    printf_s("Wind Direction is: %lf", readings[i].wind_direction);
                    printf_s("Wind Speed is: %lf", readings[i].wind_speed);
                }
            }
            else
            {
                printf_s("Date not found\n");
            }
        }
        else
        {
            printf_s("Error: %d\n");
        }

        free(readings);
        return 0;
    }






    if (option == 4)
    {
        //reading data from binary file then writing it to csv file
        FILE* pFile;
        FILE* aFile;

        errno_t error;
        int num_readings;

        time_t t;
        struct tm* tmp;
        char MY_TIME[50];
        time(&t);

        error = fopen_s(&pFile, "weather.bin", "rb");
        if (error == 0)
        {
            fread(&num_readings, sizeof(int), 1, pFile);
            readings = malloc(sizeof(struct readings) * num_readings);
            fread(readings, sizeof(struct readings), num_readings, pFile);
            fclose(pFile);
        }
        else { printf_s("Error: %d", error); }


        error = fopen_s(&aFile, "weather.txt", "w");

        if (error == 0)
        {
            fprintf(aFile, "%d readings were saved\n", num_readings);

            for (int i = 0; i < num_readings; i++)
            {
                fprintf(aFile, "Temperature: %lf\n", readings[i].temperature);
                fprintf(aFile, "Wind Direction: %lf\n", readings[i].wind_direction);
                fprintf(aFile, "Wind Speed: %lf\n", readings[i].wind_speed);
                tmp = localtime(&readings[i].time);
                strftime(MY_TIME, sizeof(MY_TIME), "%x - %I:%M%p", tmp);
            }   fprintf(aFile, "Date & Time: %s\n", MY_TIME);
            fclose(aFile);
        }
        else { printf_s("Error: %d", error); }

    }



    if (option == 5)
    {
        exit(0);
    }


    return 0;
}
  • The string in `date` read via `fgets(date, sizeof(int), stdin)` contains a \n at the end. But `MY_TIME` after `strftime(MY_TIME, sizeof(MY_TIME), "%x - %I:%M%p", tmp);` doesn't. BTW don't use all caps identifiers like `MY_TIME`. All caps identifiers are usually only used for macros. – Jabberwocky Apr 02 '20 at 12:24
  • 1
    Aside: you should check `if (readings != NULL)` *before* calling `fread(readings ...)`. – Weather Vane Apr 02 '20 at 12:38
  • Hi, thanks How would I go about fixing that. – Ciaran Mallory Apr 02 '20 at 12:39
  • 1
    Please see [Removing trailing newline character from fgets() input](https://stackoverflow.com/questions/2693776/removing-trailing-newline-character-from-fgets-input/28462221#28462221) – Weather Vane Apr 02 '20 at 12:40
  • 1
    My advice is, do *not* use `strcmp` to look for dates. If you have a date in a string, the first thing to do is convert it to a reasonable format. Do all your comparisons and searching with `struct tm` or `time_t`, but not a string. – William Pursell Apr 02 '20 at 12:41
  • 1
    `fgets(date, sizeof(int), stdin);` isn't reading enough characters? Typically, 3. It should be `fgets(date, sizeof date, stdin);`. – Weather Vane Apr 02 '20 at 12:45
  • Cheers all, I added the strcspn function after the fgets and it worked perfectly. – Ciaran Mallory Apr 02 '20 at 13:21

0 Answers0