Suggest an alternative for gets() function, using gcc compiler

28,822

Solution 1

Your problem is really not a gets() issue.

None of the scanf("%d", ...) and scanf("%lf", ...) consume the '\n' after the number and thus contribute to your issue. It is the next read of stdin to take in the '\n'. So when the next car type is read, it gets the lingering '\n'. Your 2nd car type ends up being "\n".

Use of fgets(data[i].vechileType, MAXLEN, stdin); puts a '\n' in data[i].vechileType. You likely do not want this. Your former use of gets() consumed, but did not put the '\n' in its return.

I long ago gave up doing user input with scanf() due to these subtle issues. Recommend to separate input from parsing, use fgets() and then sscanf(). Example:

char number[80];
if (fgets(number, sizeof(number), stdin)) {
  sscanf(number, "%d", &x)

Your implementation of a gets() replacement differs as follows

1) It does not return s (or NULL or error/eof).
2) It does not set eof indicator on eof. 3) Should getchar() return a '\0', your while loop errantly continues.


Recommend that if you must replace gets(), do so via fgets().

#define My_gets_N (1024 /* Some BA number */)

char *My_gets(char * str) {
  char buffer[My_gets_N];
  char *retval = fgets(buffer, sizeof(My_gets_N), stdin);
  if (retval) {
    int l = strlen(buffer);
    /* fgets() saves '\n', but gets() does not */
    if ((l > 0) && (buffer[l-1] == '\n')) {
      l--;
    }
    memcpy(str, buffer, l);
    str[l] = '\0';
    return str;
  }
  else {
    return 0;
  }
}

If you replacement solution needs to deal with string length > the fixed My_gets_N, other coding is needed.

Solution 2

You must be more specific about what went wrong with the fgets() approach, that's the one I would recommend and it does work.

Note that fgets() will input the entire line, including linefeed/carriage returns at the end, so you might need to clean those off if they're undesirable to keep.

Share:
28,822
amarVashishth
Author by

amarVashishth

computer science student

Updated on April 03, 2020

Comments

  • amarVashishth
    amarVashishth about 4 years

    Trying to input more than a single string in my program's strings array, for that used :

    scanf("%80[^\r\n]", strings[i]);

    fgets(string[i], MAXLEN, stdin);

    a custom made function was also used:

    int getString(char s[]) {
    
        char ch;
        int i=0;
    
        while( (ch = getchar()) != '\n'   &&   ch != EOF ) {
            s[i] = ch;
            ++i;
        }
    
        s[i] = '\0';
    
        fflush(stdin);
    
        return i;
    }
    

    but unable to get input with more than one string each including white spaces

    function gets() used to work earlier for me but since it is deprecated no alternative can be found

    This is where it was used :

    int getString(char s[]) {
    
    char ch;
    int i=0;
    
    while( (ch = getchar()) != '\n'   &&   ch != EOF ) {
        s[i] = ch;
        ++i;
    }
    
    s[i] = '\0';
    
    fflush(stdin);
    
    return i;
    }
    
    
    struct vechileData
    {
    char vechileType[MAXLEN];
    int begin_month;
    int end_month;
        double price;
    } data[5];
    
    
    int main(int argc, char const *argv[])
    {
    printf("Input Vechile data: \n");
    
    int i=0;
    while(i < 5) {
        printf("Input vechile Type : \n");
        fgets(data[i].vechileType, MAXLEN, stdin);
    
        printf("Input begin month : \n");
        scanf("%d", &data[i].begin_month);
    
        printf("Input end monhth : \n");
        scanf("%d", &data[i].end_month);
    
        printf("Input price : \n");
        scanf("%lf", &data[i].price);
    
        ++i;
    }
    
    printf("Input Vechile Type to display information about the vechile : \n");
    char vech[MAXLEN];
    fgets(vech, MAXLEN, stdin);
    
    i=0;
    while(i < 5) {
        if (strcmp(vech,data[i].vechileType) == 0)
        {
            printf("vechileType: %s\n", data[i].vechileType);
            printf("Begin month: %d\n", data[i].begin_month);
            printf("End month: %d\n", data[i].end_month);
            printf("Price : %lf\n", data[i].price);
        }
        ++i;        
    }
    
    return 0;
    }
    

    It skips the next input to string statement during run time, "seems to"