siannone
siannone

Reputation: 6763

C - Segmentation fault

Here's is my little C snippet that generates segmentation fault:

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

int checkTiime(char time[]);

int main(int argc, char** argv) {

    char time1[6];
    char time2[6];

    printf("Tempo 1 [hh:mm]: ");
    fgets(time1, sizeof time1, stdin);
    printf("Tempo 2 [hh:mm]: ");
    fgets(time2, sizeof time2, stdin);

    printf("Checktime: %d", checkTime(time1));

    return (EXIT_SUCCESS);
}

int checkTime(char time[]){

    long hours = 0;
    long minutes = 0;

    if(time[2] == ':') {

        if(isdigit(time[3]) && isdigit(time[4]) && isdigit(time[0]) && isdigit(time[1])) {
            hours = strtol(time[0], NULL, 10) + strtol(time[1], NULL, 10);
            minutes = strtol(time[3], NULL, 10) + strtol(time[4], NULL, 10);

            if((hours >= 0 && hours <= 23) && (minutes >= 0 && minutes <= 59)){

                return 0;

            } else {

                return 1;

            }

        } else {

            return 1;

        } 

    } else {

        return 1;

    }

}

Can someone help me. I really don't know why is giving my problems.

I also noticed that when i enter, for example, "12:34" it asks me to enter the second input, but when i write "12:34" then i delete "34" using backspace and enter "34" again it writes the second printf but doesn't allow me enter the second input and the program exits.

Personal comment:

I noticed that it's better to use gets() function to input strings beacause it doesn't count the \n character.

Upvotes: 1

Views: 152

Answers (1)

dirkgently
dirkgently

Reputation: 111306

Be careful when using fgets. Your calls require it to read in at most 6 characters before it hits either a newline or EOF. fgets considers the newline character to be a valid character and stores it too, if one such is encountered. Now, in your case, the last character is not a NULL as it should in C-style strings but a \n. You need to replace it by a NULL before you can pass it to strtol which expects a C-style NULL terminated string. So:

if (fgets(time1, sizeof time1, stdin) != NULL) {
    time1[ sizeof time1 - 1 ] = NULL;
}

Or, even better:

if (fgets(time1, sizeof time1 - 1, stdin) != NULL) {
    // hurray we have the time!
}

Or, you can have your own newline-safe fgets wrapper:

char *chomp(char *buf, size_t sz, FILE *fp, size_t *outsz) {
   char *p = fgets(buf, sz - 1, fp) ; /* make sure there is room for terminating NULL */
   if (p != NULL) {
      char *nl = strchr(buf, '\n');
      if (nl) *nl = NULL; /* replace trailing newline */
      *outsz = strlen(buf); /* recompute */
   }
   return p;
}

Upvotes: 3

Related Questions