Do I need to instruct the user to break their input in half or is there a better work around that I cannot think of?
As far as the code you've given goes, if the input word is longer than 4999 bytes then you can expect a buffer overflow. Yes, it would be wise to let someone (e.g. the user, or the guy who maintains this code next) know that's the maximum length. It's nice that you can truncate the input by using code like this: scanf("%4999s" "%*[^ \n]", numStrings);
... The %*[^ \n]
directive performs the truncation, in this case.
It'd be nicer yet if you can let the user know at the time that they overflow the buffer, but scanf
doesn't make that an easy task. What would be even nicer (for the user, I mean) is if you could use dynamic allocation.
Ahh, the problem of dynamically sized input. If it can be avoided, then avoid it. One common method to avoid this problem is to require input in the form of argv
, rather than stdin
... but that's not always possible, useful or feasible.
scanf
doesn't make this problem a particularly easy one to solve; in fact, it'd be much easier to solve if there were a similar functionality provided by %s
in the form of an interface similar to fgets
.
Without further adieu, here's an adaptation of the code I wrote in this answer, adapted for the purpose of reading (and simultaneously allocating) words in a similar procedure to that behind %s
, rather than lines in a similar procedure to that behind fgets
. Feel free to read that answer if you would like to know more about the inspiration behind it.
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
char *get_dynamic_word(FILE *f) {
size_t bytes_read = 0;
char *bytes = NULL;
int c;
do {
c = fgetc(f);
} while (c >= 0 && isspace(c));
do {
if ((bytes_read & (bytes_read + 1)) == 0) {
void *temp = realloc(bytes, bytes_read * 2 + 1);
if (temp == NULL) {
free(bytes);
return NULL;
}
bytes = temp;
}
bytes[bytes_read] = c >= 0 && !isspace(c)
? c
: '\0';
c = fgetc(f);
} while (bytes[bytes_read++]);
if (c >= 0) {
ungetc(c, f);
}
return bytes;
}