问题
I am attempting to capture input from the user via scanf:
char numStrings[5000];
printf("Enter string of numbers:\n\n");
scanf("%s", numStrings);
However, the length of the string that is inputted is 5000 characters. The translation limit in c99 is 4095 characters. 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?
回答1:
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;
}
回答2:
You can input a string a lot larger than that, the stack is at least 1MB in common OS's, it's 8MB's on Linux, so that's the actual limit, 1M is 1024KB so you could for example try with 512KB which is 524288B
char string[524288];
scanf("%524287s", string);
will be most likely ok, if it's still too small, then use malloc().
回答3:
No, you do not need to instruct the user to separate the input if it goes over a set length. The limit is on string literals, not strings. See the answer in this stackoverflow thread for more information. If you don't know what a reasonable max length is, then I would recommend using getline() or getdelim() if the delimiter that you want to use is not a line break.
来源:https://stackoverflow.com/questions/30419563/translation-limit-in-c