Obviously you'd increase the size of the buffer as it's needed. With the example I presented, only one character is necessary in order to store the '\0' character. If you know that there are exactly three characters to be read from the stream before the new line character, you'd allocate an array of four chars and pass its pointer to gets.
The example I provided uses gets. Is it unsafe?You can never, ever allocate enough memory to make gets() a safe call
In which case it's used correctly, providing you agree that a correct program works in a predictable way and an incorrect one invokes undefined behaviour.or you use your silly ungetc idea, which basically means that the whole gets call was pointless to begin with
I'm not really arguing in favour of using gets since, as I think most of you would agree, it's commonly used to write buggy programs. I just think it's silly to say that gets, as a whole, is unsafe when it's more accurate to say that it's commonly used in an unsafe way.
Also, on a slightly unrelated topic, using the "s" format specifier with scanf without a maximum field length has the same issue that gets has, but strangely, no one has seemed to comment on that in this thread when its use has been suggested on a few occasions.
edit: Some have suggested using strncpy instead of strcpy, which usually isn't a good idea. strncpy's designed specifically for copying data into a fixed 'field' for files and networks, that's why it doesn't terminate with '\0' if the size of the source string is equal to the size parameter, and why it pads the remainder of the storage with '\0's when it's less. The only real alternative you have, in standard C, is snprintf (or just strcpy after verifying the size of the source string with strlen), but some implementations provide strlcpy, strdup, and asprintf.