【问题标题】:inputting a character string using scanf()使用 scanf() 输入字符串
【发布时间】:2016-04-07 13:37:05
【问题描述】:

我开始学习在 C 中输入字符串。在下面的源代码中,我得到了一个长度为 5 的字符数组。

#include<stdio.h>
int main(void)
{
    char s1[5];
    printf("enter text:\n");
    scanf("%s",s1);
    printf("\n%s\n",s1);
    return 0;

}

当输入是:

  1. 1234567891234567,我检查了它最多可以使用 16 个元素(我不明白,因为它超过 5 个元素)。
  2. 12345678912345678,它给了我一个错误segmentation fault: 11(在这种情况下我给出了 17 个元素)
  3. 123456789123456789,错误是Illegal instruction: 4(本例我给了18个元素)

我不明白为什么会有不同的错误。这是scanf() 的行为还是C 中的字符数组?我正在阅读的那本书对这些事情没有明确的解释。仅供参考,我对指针一无所知。对此的任何进一步解释都会非常有帮助。

【问题讨论】:

  • 当输入的长度超过 4 个字符时,行为是 undefined。 未定义的行为并不意味着“必须立即崩溃”,它意味着该语言没有义务做任何特别的事情。
  • 但是当输入的长度超过 5 个字符时它不应该给我一个错误吗?
  • @buggenerator:这不是违反约束,编译器没有义务发出诊断消息,也没有要求在运行时引发错误。
  • @buggenerator 您需要了解,如果您想在做错事后立即收到消息错误,C 语言不适合您。 C 是为了效率,编译器添加最少的控件以确保它可以生成最有效的程序。

标签: c arrays scanf


【解决方案1】:

这是 scanf() 或 C 中字符数组的行为吗?

TL;DR - 不,您正面临undefined behavior 的副作用。

在您的情况下,针对类似的代码进行详细说明

 scanf("%s",s1);

你定义的地方

 char s1[5];

输入超过 4 个 char 将导致您的程序冒险进入无效的内存区域(超过分配的内存),进而调用 undefined behavior。

一旦你点击了 UB,程序的行为就无法以任何方式预测或证明。它绝对可以做任何可能(甚至不可能)的事情。

scanf() 中没有任何固有的东西可以阻止您读取过长的输入并超出缓冲区,您应该通过使用字段宽度来控制输入字符串扫描,例如

 scanf("%4s",s1);  //1 saved for terminating null

【讨论】:

  • 但是最多 16 个字符和其他任何东西都可以给我错误和Different Errors 吗?
  • 阅读undefined behavior。还要检查更新的答案以获得澄清。
  • 下一次编译运行,最多可以接受 128 或者在第 6 次崩溃,你永远不知道...
  • @buggenerator 最多 16 个字符不合适,你就不用管它了。一旦你输入超过 4 个字符,就会有一些不应该被覆盖的内存,这可能会在以后引起问题。这是未定义的行为。
【解决方案2】:

scanf 函数在读取字符串时读取到下一个空格(例如换行符、空格、制表符等)或“文件结尾”。它不知道你提供给它的缓冲区的大小。

如果您读取的字符串比提供的缓冲区长,那么它将超出范围,您将有未定义的行为。

阻止这种情况的最简单方法是为scanf 格式提供字段长度,如

char s1[5];
scanf("%4s",s1);

请注意,我使用4 作为字段长度,因为字符串终止符也需要空间。

您还可以使用需要为其提供缓冲区大小作为参数的“安全”scanf_s:

char s1[5];
scanf_s("%s", s1, sizeof(s1));

【讨论】:

  • 我在这里并不是要天真。这是否意味着在这种情况下缓冲区是 16 个字符?
  • @buggenerator no 缓冲区的长度是您在声明变量时提供的长度。所以这里的长度是 5。 ( char s1[5] )
  • @buggenerator “缓冲区大小”是您声明的数组的大小(对于终止符可能减一)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-08
  • 1970-01-01
  • 1970-01-01
  • 2018-04-11
  • 1970-01-01
  • 2012-11-22
  • 2021-07-31
相关资源
最近更新 更多