Replacing gets () with fgets ()

I tested this structure and I get a warning about using gets . Someone said to use fgets instead and replace the end with '\0' . Any recommendation, how can I change my code to do this?

 void regCars(Car reg[], int *pNrOfCars) { char again[WORDLENGTH] = "yes", model[WORDLENGTH], tmp[WORDLENGTH]; int year, milage; while (strcmp(again, "yes") == 0) { printf("Enter model:"); gets(model); printf("Enter Year:"); gets(tmp); year = atoi(tmp); printf("Enter milage:"); gets(tmp); milage = atoi(tmp); reg[*pNrOfCars] = createCar(model, year, milage); (*pNrOfCars)++; printf("Continue? (yes/no)"); gets(again); } } 
+5
source share
3 answers

You can write the mygets() utility function, which takes 2 arguments: a pointer to the target array and its size:

 char *mygets(char *dest, size_t size) { /* read a line from standard input and strip the linefeed if any */ if (fgets(dest, size, stdin)) { dest[strcspn(dest, "\n")] = '\0'); return dest; } return NULL; } void regCars(Car reg[], int *pNrOfCars) { char model[WORDLENGTH], tmp[WORDLENGTH]; int year, milage; for (;;) { printf("Enter model:"); if (!mygets(model, sizeof mode)) break; printf("Enter year:"); if (!mygets(tmp, sizeof tmp)) break; year = atoi(tmp); printf("Enter milage:"); if (!mygets(tmp, sizeof tmp)) break; milage = atoi(tmp); reg[*pNrOfCars] = createCar(model, year, milage); (*pNrOfCars)++; printf("Continue? (yes/no)"); if (!mygets(tmp, sizeof(tmp)) break; if (strcmp(again, "yes") != 0) break; } } 

Note that you can decompose more code using the prompt() function, which displays the question and reads the answer:

 char *prompt(const char *message, char *dest, size_t size) { printf("%s ", message); fflush(stdout); /* read a line from standard input and strip the linefeed if any */ if (fgets(dest, size, stdin)) { dest[strcspn(dest, "\n")] = '\0'); return dest; } return NULL; } void regCars(Car reg[], int *pNrOfCars) { char model[WORDLENGTH], tmp[WORDLENGTH]; int year, milage; for (;;) { if (!prompt("Enter model:", model, sizeof mode)) break; if (!prompt("Enter year:", tmp, sizeof tmp)) break; year = atoi(tmp); if (!prompt("Enter milage:", tmp, sizeof tmp)) break; milage = atoi(tmp); reg[*pNrOfCars] = createCar(model, year, milage); (*pNrOfCars)++; if (!prompt("Continue? (yes/no)", tmp, sizeof(tmp)) break; if (strcmp(again, "yes") != 0) break; } } 

Also note that this function must take the size of the reg array in order to stop asking for more input when it is full. As currently indicated, it has the same drawback as gets() , unexpected input will cause undefined behavior.

0
source

This is a little more complicated than it sounds. There isnโ€™t much sense, just replacing it with fgets () gets it if you then process the truncated string on input that is too long and treat it as real. You simply replaced the undefined behavior with the wrong behavior.

 if( fgets(line, sizeof(line), fp) ) { if(!strchr(line, '\n')) { /* line is too long, what you do is up to you, but normally we will discard it */ int ch; while( (ch = fgetc(fp)) != EOF) if(ch == '\n') break; } else { /* line is a normal line with a trailing '\n' (gets trims the '\n') */ } } 
+1
source

Just do for example

 if (NULL != fgets(model, WORDLENGTH, stdin)) /* Read the string. */ { model[strcspn(model, "\r\n")] = '\0'; /* Cut off \n and/or \r, if any. */ } 
0
source

Source: https://habr.com/ru/post/1257889/


All Articles