【问题标题】:How to get string from input in C language如何从C语言的输入中获取字符串
【发布时间】:2017-10-27 19:05:50
【问题描述】:

这是我尝试过的:

printf("Please venter first string\n");
char str[127];
scanf_s("%s", &str);

得到了这个异常:

在 strcmp.exe 中的 0x0FD2C700 (ucrtbased.dll) 处引发异常: 0xC0000005:访问冲突写入位置0x00500000。

我也试试这个:

printf("Please venter first string\n");
char str[127];
scanf_s("%d", &str);

在这种情况下也不例外,但我得到了又长又奇怪的字符串。

【问题讨论】:

  • scanf_s("%s", &str) --> scanf_s("%s", str, sizeof(str))
  • @BLUEPIXY s of scanf_s 表示“安全”...好吧,您仍然需要检查警告...
  • @Jean-FrançoisFabre 什么警告?
  • @Jean-FrançoisFabre 我非常同意,这比scanf 更难做到——它已经有了长度限制功能。
  • “如何从 C 语言的输入中获取字符串”? --> fgets(str, sizeof str, stdin); 快乐的编程生活。 scanf_sscanf 导致 road to perdition

标签: c input


【解决方案1】:

让我们首先考虑使用标准scanf。如果你写

scanf("%s", &str);

那将是不正确的(尽管它可能有效)。将数组传递给函数时,它会衰减为指向第一个元素的指针,这是scanf 所要求的,所以该行应该是

scanf("%s", str);

如果要限制输入长度以防止缓冲区溢出,可以这样(比数组长度小一以允许nul 终止符)

scanf("%126s", str);

据称更安全的函数 scanf_s 需要为每个格式类型 %c%s%[] 传递一个额外的大小参数,所以下一行(在更正 & 之后)

scanf_s("%s", str);

缺少该参数,编译器应该发出警告。代码应该是

scanf_s("%s", str, sizeof str);

但即使这样也是不够的。 Xscanf 系列函数返回成功输入的值的数量。由于用户(甚至我自己)在输入正确的输入(甚至可能是恶意的)方面出了名的糟糕,因此您必须始终检查数据是否正确输入。比如

if(scanf_s("%s", str, sizeof str) != 1) {
    // inform user and retry etc. etc.
}

正如@chux 所说,最好使用fgets 获取输入,然后通过各种方式处理它,例如sscanfstrtokstrsep 或更直接地分析字符串。在这种情况下,使用sscanf,您可以多次尝试处理输入,但使用scanf,您只有一次机会。请注意,strtokstrsep 修改了字符串,因此如果您需要多次尝试对其进行解码,则需要使用副本。


在你的第二个例子中

scanf_s("%d", &str);

你得到“没有例外,只有一个长而奇怪的字符串”,但你应该得到一个编译器警告:

警告 C4477:“scanf_s”:格式字符串“%d”需要参数 输入“int ”,但可变参数 1 的类型为“char ()[127]”

请注意,您没有将 str 初始化为“空字符串”,如果在输入错误后继续处理您认为是好的字符串,则可能会发生坏事。

【讨论】:

  • &str是对象的地址,str衰减到第一个元素的地址,不一定是同一个东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-07
  • 1970-01-01
相关资源
最近更新 更多