我想知道在使用scanf时/之前是否有任何方法可以动态分配一些内存。这意味着在初始化时不需要提供char *
大小。而不是这样,所需的内存量将根据输入字符串的大小进行分配(这意味着:在输入之后)。
目前我找不到其他解决方案,只有在输入之前分配特定数量的内存,所以在知道输入的大小之前:
char str[10];
scanf("%s", str);
我知道这不安全:如果输入超过10个字符,程序将写入未分配的内存,这可能导致段错误或类似的东西。
答案 0 :(得分:1)
正如评论中所指出的,%m我相信会解决您的问题
另一种方法是将输入限制为您知道已分配给变量的数字字节,例如%10s将仅输入10个字符 然后重新分配你的输入变量以便在下一次调用scanf时为更多字符输入空间,你需要在下一次调用中传递str& str [10],这样它就不会覆盖先前的输入
答案 1 :(得分:1)
来自stdin
的用户输入很棘手。
OP'如果输入超过10个字符,程序将写入未分配的内存"是一个1分的问题。如果输入长于 9 ,程序将在未分配的内存上写入。
char str[10];
scanf("%s", str);
getline();
,正如good answer所建议的那样,是典型的解决方案。
我拒绝在扫描期间进行动态分配的想法"作为一个很好的设计目标。允许无限输入的程序容易被滥用。它允许用户压倒系统资源。 优质代码首先验证输入。不再是Heartbleed。
相反,我建议评估stdin
输入合理的输入长度,不论是10,1000还是1,000,000,并提供2x左右的缓冲区。
#define MAX_EXPECTED_SIZE 100
char buf[MAX_EXPECTED_SIZE * 2];
if (fgets(buf, sizeof buf, stdin)) {
size_t len = strlen(buf);
if (len + 1 == sizeof buf && buf[len] != '\n') {
// Assume hostile input and act accordingly. Possibly exiting with message.
// or consume rest of line
int ch;
while ((ch = getchar()) != '\n' && ch != EOF);
return ERROR_LONG_LINE
}
// Use buf[]
}
代码可以分配合适大小的内存,然后需要保留buf
的副本。
答案 2 :(得分:0)
使用getline功能
# on home pc
export http_proxy=http://127.0.0.1:45849
export https_proxy=http://127.0.0.1:45849
示例 Try Online
ssize_t getline(char **lineptr, size_t *n, FILE *stream);