代码之家  ›  专栏  ›  技术社区  ›  Prometheus

C编程中字符串的scanf(%s),a)scanf(“%[^\n]s”,a)和get(a)之间有什么区别?

  •  -2
  • Prometheus  · 技术社区  · 8 年前

    scanf("%s") , scanf(”%[^\n]s") gets(a)

    scanf("%[^\n]s", a)
    
    scanf("%s", a)
    
    gets(a)
    

    获取字符数组输入的三种方法之间的主要区别是什么?

    2 回复  |  直到 8 年前
        1
  •  4
  •   ad absurdum    8 年前

    scanf("%s",a); a 是一个100的数组 char s %99s 应使用;这为 \0 自动添加的终止符 scanf()

    也不 scanf("%s[^\n]",a); 也没有 scanf("%[^\n]s", a); scanf("%[^\n]",a); . 这个 %[] 扫描集 指令。没有必要遵循 带有 s ,这只能说明 scanf() 匹配文字 完成后输入 %[] ^\n 指示所有字符 除了 因为换行符应该匹配,所以该指令将匹配字符,直到遇到换行符,并且换行符将保留在输入流中。关于指定最大宽度的相同建议也适用于此处: %99[^\n] 是一个100的数组 烧焦 %[^\n] 指令将匹配任何不是 \n 跳过前导空格字符(但前导 输入将导致指令立即失败,而不进行赋值) %s ,并将读取 线

    puts(a); gets() 在此方法列表中收集输入。

    gets(a); is an unsafe function 这在C99中被弃用,在C11中完全从语言中删除。您不应出于任何原因使用此功能。此函数用于获取一行输入,读取字符,直到遇到换行符或到达文件末尾。丢弃换行符;它不存储在 ,并且不会返回到输入流。因此,当 获取() puts() ,它在打印其参数后自动打印换行符。

    最后,要了解更多信息,请参阅 fgets() . 此函数获取一行输入,但采用大小参数,以避免缓冲区溢出。根据我之前的例子 char a[100]; , fgets()

    fgets(a, 100, stdin);
    

    fgets(a, sizeof a, stdin);
    

    在这里 最多读取 少一个字符 大于size参数指定的数字,为 \0 已读取,则存储在 . 因为新行没有被丢弃, puts() 在这里效果不太好;通常,换行符需要在使用 fgets()

        2
  •  2
  •   user2371524 user2371524    8 年前

    首先,他们 所有人都有未定义的行为 你不能提前知道 ,但通过指针,您提供了存储此数据的存储空间,并且此存储空间具有一定的固定大小。因此,有 可能的输入 溢流 你的缓冲器。你不应该使用 代码中的这些行。

    也就是说:

    • gets() 线 ,因为有 无法安全使用 . 永远不要使用它。它一直是 来自C11中的C标准,因此无论如何只能与旧标准一起使用。正确的更换方法是 char a[100]; fgets(a, sizeof a, stdin); 不过,将换行符存储在缓冲区中。

    • scanf("%[^\n]s", ...) 也将读取 [] ^ 除了 换行符。因此,换行符 这边这个 s 将在输入中搜索 字面上 ,这不是你的意思。 [] 不同的 char a[100]; scanf("%99[^\n]", a); 少一个 大于缓冲区大小,因为 scanf() 不计算 '\0'

    • scanf("%s", ...) “,也就是说,它首先停止 空白 char a[100]; scanf("%99s", a); .