为了账号安全,请及时绑定邮箱和手机立即绑定

如何防止扫描导致C中的缓冲区溢出?

如何防止扫描导致C中的缓冲区溢出?

C++ C
叮当猫咪 2019-06-10 20:22:49
如何防止扫描导致C中的缓冲区溢出?我使用以下代码:while ( scanf("%s", buf) == 1 ){防止可能的缓冲区溢出从而传递随机长度字符串的最佳方法是什么?我知道可以通过调用以下命令来限制输入字符串:while ( scanf("%20s", buf) == 1 ){但我更希望能够处理用户输入的任何内容。或者这不能安全地使用scanf,我应该使用fget?
查看完整描述

3 回答

?
精慕HU

TA贡献1845条经验 获得超8个赞

在他们的书里编程实践(这很值得一读),克尼汉和派克讨论了这个问题,他们用snprintf()创建具有正确缓冲区大小的字符串以传递到scanf()功能家族。实际上:

int scanner(const char *data, char *buffer, size_t buflen){
    char format[32];
    if (buflen == 0)
        return 0;
    snprintf(format, sizeof(format), "%%%ds", (int)(buflen-1));
    return sscanf(data, format, buffer);}

注意,这仍然将输入限制在作为“缓冲区”提供的大小上。如果您需要更多的空间,那么您必须进行内存分配,或者使用一个非标准的库函数来为您分配内存。


注意,POSIX 2008(2013)版scanf()函数族支持格式修饰符m(赋值-分配字符)用于字符串输入(%s%c%[)。而不是采取char *争论,这需要一个char **参数,并为其读取的值分配必要的空间:

char *buffer = 0;if (sscanf(data, "%ms", &buffer) == 1){
    printf("String is: <<%s>>\n", buffer);
    free(buffer);}

如果sscanf()函数无法满足所有转换规范,然后它为其分配的所有内存。%ms-在函数返回之前释放类似的转换。


查看完整回答
反对 回复 2019-06-10
?
MYYA

TA贡献1868条经验 获得超4个赞

如果您正在使用GCC,则可以使用GNU分机。a为您分配内存以保存输入的说明符:

int main(){
  char *str = NULL;

  scanf ("%as", &str);
  if (str) {
      printf("\"%s\"\n", str);
      free(str);
  }
  return 0;}

编辑:正如乔纳森所指出的,您应该咨询scanf说明符可能与手册页不同(%m),您可能需要在编译时启用某些定义。


查看完整回答
反对 回复 2019-06-10
?
素胚勾勒不出你

TA贡献1827条经验 获得超9个赞

在大多数情况下,fgetssscanf做这份工作。另一件事是编写自己的解析器,如果输入格式化良好的话。还请注意,您的第二个示例需要进行一些修改才能安全地使用:

#define LENGTH          42#define str(x)          # x#define xstr(x)       
  str(x)/* ... */ int nc = scanf("%"xstr(LENGTH)"[^\n]%*[^\n]", array);

上面的输入流向上丢弃,但不包括换行符(\n)性格。您将需要添加一个getchar()来消费这个。还请检查是否到达了流的末尾:

if (!feof(stdin)) { ...

仅此而已。


查看完整回答
反对 回复 2019-06-10
  • 3 回答
  • 0 关注
  • 807 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信