Sunday, 22 May 2016

stdin - How do I read a string entered by the user in C?



I want to read the name entered by my user using C programmes.



For this I wrote:



char name[20];


printf("Enter name: ");
gets(name);


But using gets is not good, so what is a better way?


Answer



You should never use gets (or scanf with an unbounded string size) since that opens you up to buffer overflows. Use the fgets with a stdin handle since it allows you to limit the data that will be placed in your buffer.



Here's a little snippet I use for line input from the user:




#include 
#include

#define OK 0
#define NO_INPUT 1
#define TOO_LONG 2
static int getLine (char *prmpt, char *buff, size_t sz) {
int ch, extra;


// Get line with buffer overrun protection.
if (prmpt != NULL) {
printf ("%s", prmpt);
fflush (stdout);
}
if (fgets (buff, sz, stdin) == NULL)
return NO_INPUT;

// If it was too long, there'll be no newline. In that case, we flush
// to end of line so that excess doesn't affect the next call.

if (buff[strlen(buff)-1] != '\n') {
extra = 0;
while (((ch = getchar()) != '\n') && (ch != EOF))
extra = 1;
return (extra == 1) ? TOO_LONG : OK;
}

// Otherwise remove newline and give string back to caller.
buff[strlen(buff)-1] = '\0';
return OK;

}


This allows me to set the maximum size, will detect if too much data is entered on the line, and will flush the rest of the line as well so it doesn't affect the next input operation.



You can test it with something like:



// Test program for getLine().

int main (void) {

int rc;
char buff[10];

rc = getLine ("Enter string> ", buff, sizeof(buff));
if (rc == NO_INPUT) {
// Extra NL since my system doesn't output that on EOF.
printf ("\nNo input\n");
return 1;
}


if (rc == TOO_LONG) {
printf ("Input too long [%s]\n", buff);
return 1;
}

printf ("OK [%s]\n", buff);

return 0;
}


No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...