我正在尝试用 C 正确处理用户输入,特别是从用户那里读取文件路径时。
然而,我有一些担忧:
- 我如何重构此代码来处理动态内存分配。
- 当长度未知时,应如何正确处理用户输入的动态内存分配?
- 接受用户输入的文件路径最安全的方法是什么?
我当前的代码:
#include <stdio.h>
int main() {
char filePath[1024];
printf("Please provide file to encrypt (File Path): ");
scanf("%1024s", filePath); // Is this safe?
printf("You entered: %s\n", filePath);
return 0;
}
我在微软的网站上找到一个来源,建议我为%s
格式说明符指定一个宽度scanf
(例如,%1024s
而不是%s
),但它仍然是固定大小,我希望它动态分配。
正如评论中所述,您最好利用标准库
fgets
函数,它允许您指定缓冲区的大小以避免缓冲区溢出问题。使用
scanf
带%s
或不带宽度说明符也会限制您读取一个空格分隔的字符串。这会禁止输入空格。如果您想读取长度未知的整行,则需要使用标准库之外的方法或自己重新发明轮子。这应该不难。我花了几分钟就完成了以下内容,也许还有改进的空间,但这也不会花很长时间。
关键过程是分配一个初始缓冲区,然后逐个字符地读入,直到命中
EOF
或换行符。如果长度达到缓冲区的限制,则重新分配。有两个常见的内存管理缺陷:
realloc
可能需要复制缓冲区。这很昂贵。增加 2 1倍(乘以),您的对 的调用将呈对数增长。从更大的初始预算大小开始也是一个选择。realloc
realloc
调用测试时,在分配原始缓冲区之前先检查是否成功。如果没有,并且realloc
失败,您将无法访问最初分配的内存,从而导致内存泄漏。对此的进一步改进可能是将
size_t
指针作为参数并允许函数将读取字符串的长度写入变量,这样随后不需要计算输入字符串的大小strlen
。1理想的内存增长率存在一些争议。请参阅:动态分配数组的理想增长率是多少?
尝试使用,
getline(&buffer,&size,stdin);
因为它为输入动态分配内存。你可以简单地得到一个像这样的工作代码: