Search code examples
cfunctionfiletextatoi

How to read a time like "10:55" from a text file so that we can do calculation with it in C programming language?


I am trying to read a time like data (i.e. 10:55) from a text file and assign it in such a way that I can do calculations with it. For instance if I want to covert 10 hrs and 55 minutes from 10:55 into minutes: 10*60+55=655. But 10:55 contains ':' so I can't directly assign it to an integer. So far I was able to solve this problem using atoi(char *ptr)function which coverts the numbers inside a string into integer type data.The code is running just fine but I am not sure how this function works. Because the string "10:55" contains a non numeric value so shouldn't it return junk value immediately when it detects ":".But in my case it returns 10 and then, after I shifted the pointer by 3 places it gives 55. So it will be really helpful if someone elaborates how this function exactly works.

Finally is there any other way of solving this problem without using atoi() function and only using basic C programming techniques. If yes then please share your code and explanation with me.Thanks a lot for helping. Here is my code:

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

int main(void)
{
    int hh,mm;
    char startingtime[6];
    int strtimearr[2];

    FILE *start=fopen("start.txt","w");
    if(start==NULL)
    {
        printf("FILE DOES NOT EXIST");


    }

    printf("START TIME\n");
    printf("->HOUR(hh):");
    scanf("%d",&hh);
    printf("->MINUTE(mm):");
    scanf("%d",&mm);

    fprintf(start,"%d:%d",hh,mm);
    fclose(start);

    start = fopen("start.txt", "r");

    if(start==NULL)
    {
        printf("FILE DOES NOT EXIST");


    }
    fscanf(start, "%s", startingtime);
    fclose(start);

    //puts(startingtime);

    char *s1= startingtime;


    strtimearr[0] = atoi(s1);
    strtimearr[1] = atoi(s1+3);



    printf("Time : %d:%d \nconverted to minute : %d",strtimearr[0],strtimearr[1],(strtimearr[0]*60+strtimearr[1]));


}

Solution

  • It works but is not robust. If the user gives a number greater than 99 for hour or minute, you will write more than 5 bytes to the file. Then at read time you will read past end of startingtime array invoking Undefined Behavious. On the other hand, if hour is less than 10, the minute field will start at position 2 and not 3.

    For IO, the rule is be strict when writing and tolerant when reading. So I advise you to use a stricter format for writing: fprintf(start,"%2d:%02d",hh,mm); or fprintf(start,"%02d:%02d",hh,mm); to be consistent for values less than 10.

    At read time, you could at least limit size with fscanf(start, "%5s", startingtime); and then decode with sscanf:

    int cr = sscanf(startingtime, "%d:%d", strtimearr, strtimearr+1);
    

    Or directly decode at read time with fscanf:

    int cr = fscanf(start, "%d:%d", strtimearr, strtimearr+1);
    

    and control that cr is 2 before printing the result.