Ad

While-loop In C Language For Subtraction Operation

- 1 answer

Here, I have this code which gives the difference between 2 dates.

I used the mktime function which takes the user input from Scanf and then we do a subtraction.

We should input two lines, in each line 5 parameters: (year month day hour minute)

After that, we subtract the second line from the first line and the difference is in minutes.

for ex:

2020 10 5 17 0
2020 11 5 17 0
output: 1440 //minutes because the difference here is only one day

And now, my teacher asked me to make it work for more than 2 dates. We should subtract Each line from the Previous line. So, if we have 5 dates, the answer should be 4 values.

for ex:

2020 10 5 17 0
2020 11 5 17 0
2020 12 5 17 0
2020 13 5 17 0
2020 14 5 17 0
output: 
1440
1440
1440
1440

I really got stuck at this point because I tried to use an array but he told me it would be better if I use a while loop which preserves the previous value. But still I don't know how to do it.

This is my code:

#include <stdio.h>
#include <time.h>
int main ()
{
  struct tm start_date;
  struct tm end_date;
  time_t start_time, end_time;
  double seconds;


  scanf("%d%d%d%d%d", &start_date.tm_year, &start_date.tm_mon, &start_date.tm_mday, &start_date.tm_hour, &start_date.tm_min);

  scanf("%d%d%d%d%d", &end_date.tm_year, &end_date.tm_mon, &end_date.tm_mday, &end_date.tm_hour, &end_date.tm_min);

  start_date.tm_year = (start_date.tm_year-1900);
  end_date.tm_year = (end_date.tm_year-1900);

  start_date.tm_sec = 0;
  end_date.tm_sec = 0;

  start_date.tm_isdst = -1;
  end_date.tm_isdst = -1;

  start_time = mktime(&start_date);
  end_time = mktime(&end_date);

  seconds = difftime(end_time, start_time);

  printf ("%.f \n", (seconds/60));

  return 0;
}



Ad

Answer

if you can write the difference after each line from the second the changes from your initial code are very small and you do not need an array :

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

int main ()
{
  struct tm date;

  if (scanf("%d%d%d%d%d", &date.tm_year, &date.tm_mon, &date.tm_mday, &date.tm_hour, &date.tm_min) == 5) {
    time_t start_time, end_time;

    date.tm_year = (date.tm_year-1900);
    date.tm_sec = 0;
    date.tm_isdst = -1;
    start_time = mktime(&date);

    while (scanf("%d%d%d%d%d", &date.tm_year, &date.tm_mon, &date.tm_mday, &date.tm_hour, &date.tm_min) == 5) {
      double seconds;

      date.tm_year = (date.tm_year-1900);
      date.tm_sec = 0;
      date.tm_isdst = -1;
      end_time = mktime(&date);

      seconds = difftime(end_time, start_time);

      printf ("%.f \n", (seconds/60));
      start_time = end_time;
    }
  }

  return 0;
}

Compilation and execution :

[email protected]:/tmp $ gcc -Wall d.c
[email protected]:/tmp $ ./a.out
2020 10 5 17 0
2020 11 5 17 0
43200 
2020 12 5 17 0
44640 
<control d>[email protected]:/tmp $ 

note the inputs you give are separated by one month rather than day

If you want to print the differences at the end you can just save these differences, it is useless to save the dates, for instance using a dynamic array :

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

int main ()
{
  struct tm date;

  if (scanf("%d%d%d%d%d", &date.tm_year, &date.tm_mon, &date.tm_mday, &date.tm_hour, &date.tm_min) == 5) {
    time_t start_time, end_time;
    double * seconds = malloc(0);
    size_t ndiff = 0;
    size_t i;

    date.tm_year = (date.tm_year-1900);
    date.tm_sec = 0;
    date.tm_isdst = -1;
    start_time = mktime(&date);

    while (scanf("%d%d%d%d%d", &date.tm_year, &date.tm_mon, &date.tm_mday, &date.tm_hour, &date.tm_min) == 5) {
      double * s = realloc(seconds, sizeof(double) * (ndiff + 1));

      if (s == NULL) {
        puts("not enough memory");
        break;
      }

      date.tm_year = (date.tm_year-1900);
      date.tm_sec = 0;
      date.tm_isdst = -1;
      end_time = mktime(&date);

      seconds = s;
      seconds[ndiff++] = difftime(end_time, start_time);

      start_time = end_time;
    }

    for (i = 0; i < ndiff; ++i)
      printf ("%.f \n", seconds[i]/60);

    free(seconds);
  }

  return 0;
}

Compilation and execution :

[email protected]:/tmp $ gcc -Wall d.c
[email protected]:/tmp $ ./a.out
2020 10 5 17 0
2020 10 6 17 0
2020 10 7 17 0
2020 10 8 17 0
2021 10 8 17 0
<control-d>1440 
1440 
1440 
525600 
[email protected]:/tmp $ 

Note the scanf and next lines up to the call of mktime are the same for the initial date and the next, it it better to define a function doing that to not duplicate the code. An other way is to have the code only one time and using ndiff to know if you can or not compute the difference :

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

int main ()
{
  struct tm date;
  time_t start_time;
  double * seconds = malloc(0);
  int ndiff = -1;
  int i;

  while (scanf("%d%d%d%d%d", &date.tm_year, &date.tm_mon, &date.tm_mday, &date.tm_hour, &date.tm_min) == 5) {
    time_t end_time;

    date.tm_year = (date.tm_year-1900);
    date.tm_sec = 0;
    date.tm_isdst = -1;
    end_time = mktime(&date);

    if (ndiff == -1)
      ndiff = 0;
    else {
      double * s = realloc(seconds, sizeof(double) * (ndiff + 1));

      if (s == NULL) {
        puts("not enough memory");
        break;
      }

      seconds = s;
      seconds[ndiff++] = difftime(end_time, start_time);
    }
    start_time = end_time;
  }

  for (i = 0; i < ndiff; ++i)
    printf ("%.f \n", seconds[i]/60);

  free(seconds);

  return 0;
}
Ad
source: stackoverflow.com
Ad