我写了一些C代码来读取两个数字和一个运算符:
int Numberone = 0, Numbertwo = 0;
char Op;
scanf_s("%d %c %d", &Numberone, &Op, &Numbertwo);
用户输入他的输入(5 + 2)后,变量具有以下值:Numberone = 5,Op = +和Numbertwo = 0.但这是错误的。第二个应该是2.我如何改进我的代码?为什么我的代码错了?
答案 0 :(得分:1)
您正在使用scanf_s
(请注意_s
),这对于%s
或%c
类型的每个参数都需要最大长度参数(例如,参见{ {3}}在cppreference.com上):
scanf_s
:与scanf
相同,但%c
,%s
和%[
除外 转换说明符每个都期望两个参数(通常的指针和 类型rsize_t
的值,表示接收阵列的大小, 用1
读入单个字符时可能%c
。
因此,%c
格式的参数太少,应该是:
scanf_s("%d %c %d", &Numberone, &Op, (rsize_t) 1, &Numbertwo);
答案 1 :(得分:0)
首先,您不应该使用scanf_s()
。微软的编译器告诉你使用它,但最好忽略它。虽然scanf_s()
的目的是提高安全性,但却会更加安全。通过要求c
,s
和[
转换的缓冲区大小,它是Microsoft专有扩展,因此使用它,您锁定到微软编译器。您的实际问题是,您未在通话中传递缓冲区大小,scanf_s()
会假定&Numbertwo
是缓冲区长度。
情况更糟,因为C标准还包括scanf_s()
。标准版本要求缓冲区大小为元素计数为rsize_t
,而Microsoft版本要求字节数为unsigned
,所以他们巧妙地不相容!恕我直言,这整个功能无论如何都是不必要的,只需使用字段宽度就可以使用普通scanf()
编写安全代码。
因为scanf()
不适合从解析错误中恢复,所以您不应该直接使用它来进行交互式输入,而是读取整行并解析它(例如使用{{ 1}})。您的代码可能如下所示:
sscanf()
相应地处理错误。