Translation limit in C

做~自己de王妃 提交于 2019-12-13 08:25:27

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!