C中的翻译限制
Translation limit in C
我正在尝试通过 scanf 捕获用户的输入:
char numStrings[5000];
printf("Enter string of numbers:\n\n");
scanf("%s", numStrings);
但是,输入的字符串长度为5000个字符。 c99 中的翻译限制是 4095 个字符。我是否需要指示用户将他们的输入分成两半,或者是否有我想不到的更好的解决方法?
你可以输入一个比那个大很多的字符串,堆栈至少是 1MB 公共 OS 的,它是 8MB 的 Linux,所以这是实际的限制,1M 是 1024KB例如,您可以尝试使用 512KB,即 524288B
char string[524288];
scanf("%524287s", string);
应该可以吧,如果还是太小,就用malloc()
.
不,如果超过设定的长度,您不需要指示用户分隔输入。限制是字符串文字,而不是字符串。有关详细信息,请参阅 this Whosebug 线程中的答案。如果您不知道合理的最大长度是多少,那么如果您要使用的分隔符不是换行符,我建议您使用 getline() 或 getdelim()。
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?
就您提供的代码而言,如果输入字长于 4999 字节,则可能会发生缓冲区溢出。是的,让 某人 (例如用户或接下来维护此代码的人)知道这是最大长度是明智的。很高兴您可以使用如下代码截断输入:scanf("%4999s" "%*[^ \n]", numStrings);
... %*[^ \n]
指令执行截断,在本例中。
如果您能在用户溢出缓冲区时让他们知道就更好了,但是 scanf
这并不是一件容易的事。如果您可以使用动态分配,那会更好(我的意思是对用户而言)。
啊,动态输入大小的问题。如果可以避免,那就避免吧。避免此问题的一种常用方法是要求以 argv
的形式输入,而不是 stdin
... 但这并不总是可能的、有用的或可行的。
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
.
不多说了,这里是我在 中编写的代码的改编版,适用于在类似过程中读取(并同时分配) 单词 %s
后面的那个,而不是 行 后面的那个,过程类似于 fgets
后面的那个。如果您想了解更多关于它背后的灵感,请随时阅读该答案。
#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
: '[=10=]';
c = fgetc(f);
} while (bytes[bytes_read++]);
if (c >= 0) {
ungetc(c, f);
}
return bytes;
}
我正在尝试通过 scanf 捕获用户的输入:
char numStrings[5000];
printf("Enter string of numbers:\n\n");
scanf("%s", numStrings);
但是,输入的字符串长度为5000个字符。 c99 中的翻译限制是 4095 个字符。我是否需要指示用户将他们的输入分成两半,或者是否有我想不到的更好的解决方法?
你可以输入一个比那个大很多的字符串,堆栈至少是 1MB 公共 OS 的,它是 8MB 的 Linux,所以这是实际的限制,1M 是 1024KB例如,您可以尝试使用 512KB,即 524288B
char string[524288];
scanf("%524287s", string);
应该可以吧,如果还是太小,就用malloc()
.
不,如果超过设定的长度,您不需要指示用户分隔输入。限制是字符串文字,而不是字符串。有关详细信息,请参阅 this Whosebug 线程中的答案。如果您不知道合理的最大长度是多少,那么如果您要使用的分隔符不是换行符,我建议您使用 getline() 或 getdelim()。
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?
就您提供的代码而言,如果输入字长于 4999 字节,则可能会发生缓冲区溢出。是的,让 某人 (例如用户或接下来维护此代码的人)知道这是最大长度是明智的。很高兴您可以使用如下代码截断输入:scanf("%4999s" "%*[^ \n]", numStrings);
... %*[^ \n]
指令执行截断,在本例中。
如果您能在用户溢出缓冲区时让他们知道就更好了,但是 scanf
这并不是一件容易的事。如果您可以使用动态分配,那会更好(我的意思是对用户而言)。
啊,动态输入大小的问题。如果可以避免,那就避免吧。避免此问题的一种常用方法是要求以 argv
的形式输入,而不是 stdin
... 但这并不总是可能的、有用的或可行的。
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
.
不多说了,这里是我在 %s
后面的那个,而不是 行 后面的那个,过程类似于 fgets
后面的那个。如果您想了解更多关于它背后的灵感,请随时阅读该答案。
#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
: '[=10=]';
c = fgetc(f);
} while (bytes[bytes_read++]);
if (c >= 0) {
ungetc(c, f);
}
return bytes;
}