I usually use the following function:
#include <stdio.h>
#include <string.h>
#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;
}
It uses the buffer-overflow-safe fgets with some supporting code to figure out if the line you entered was too long.
You can of course, read partial lines and perform memory re-allocations to store an arbitrary sized input string but usually it's more than adequate to just set a large enough upper boundary and allow for that (say 1K for example). If anyone enters more than that for their name or address, they're probably just being silly :-)
I've actually used that trick (partial reads and reallocs) to do user input before but, to be honest, the need for it was so rare that it didn't make it into my "important source code snippets" repository.
The use of fgets prevents the possibility of buffer overflow which is the big danger to user input.
If you want to test that code, try adding:
int main (void) {
int rc;
char buff[10];
rc = getLine ("Enter string> ", buff, sizeof(buff));
if (rc == NO_INPUT) {
printf ("No input\n");
return 1;
}
if (rc == TOO_LONG) {
printf ("Input too long\n");
return 1;
}
printf ("OK [%s]\n", buff);
return 0;
}
and some sample runs:
pax> ./qq
Enter string> hi bob
OK [hi bob]
pax> ./qq
Enter string>
No input
pax> ./qq
Enter string> hi ho the merry oh
Input too long
(that second one was entering CTRLD, an immediate end of file).