我一直在尝试自己寻找答案,但是我找不到。 我想插入一部分编程代码,可以读取像“Hello”这样的字符串,并在需要时存储并显示它,以便
printf(“%s”,blah);
产生Hello
。以下是使我困扰的代码部分。
char name[64];
scanf_s("%s", name);
printf("Your name is %s", name);
我知道
printf
不是问题所在,程序在提示后输入后会崩溃。请帮忙?从ISO/IEC 9899:2011标准的附录K.3.5.3.2中fscanf_s()
的规范可以得知:
fscanf_s
函数等效于fscanf
函数,但c
、s
和[
转换说明符适用于一对参数(除非通过*
指示抑制赋值)。这些参数中的第一个与fscanf
相同。该参数紧随在参数列表中的第二个参数后面,其类型为rsize_t
,并给出了由该对参数的第一个参数指向的数组中元素的数量。如果第一个参数指向标量对象,则将其视为具有一个元素的数组。
还有:
scanf_s
函数等效于在scanf_s
的参数之前插入stdin
参数的fscanf_s
函数。
MSDN表示类似的事情(scanf_s()
和fscanf_s()
)。
你的代码没有提供长度参数,因此使用其他数字。它找到的值不确定,所以代码会出现异常行为。你需要像下面这样做一些更多的东西,其中换行符有助于确保实际看到输出。
char name[64];
if (scanf_s("%s", name, sizeof(name)) == 1)
printf("Your name is %s\n", name);
scanf_s
的第三个参数不应该被强制转换为(unsigned int)
吗?因为sizeof
返回的是size_t
类型的值。 - Spikatrixrsize_t
(请参见答案中的引用),但是K.3.3 常见定义 <stddef.h>
表示(完整内容如下):
头文件 <stddef.h> 定义了一种类型。该类型是
rsize_t
它是类型 size_t
. 并引用脚注 385,其中说:请参阅 <stdint.h>
中 RSIZE_MAX
宏的描述。 对 RSIZE_MAX
的讨论更加广泛,但意图通常应小于 SIZE_MAX
,建议大小为 SIZE_MAX >> 1
。 - Jonathan Leffler我在大学课程中经常使用这个,所以在Visual Studio中应该可以很好地工作(已在VS2013中测试):
char name[64]; // the null-terminated string to be read
scanf_s("%63s", name, 64);
// 63 = the max number of symbols EXCLUDING '\0'
// 64 = the size of the string; you can also use _countof(name) instead of that number
// calling scanf_s() that way will read up to 63 symbols (even if you write more) from the console and it will automatically set name[63] = '\0'
// if the number of the actually read symbols is < 63 then '\0' will be stored in the next free position in the string
// Please note that unlike gets(), scanf() stops reading when it reaches ' ' (interval, spacebar key) not just newline terminator (the enter key)
// Also consider calling "fflush(stdin);" before the (eventual) next scanf()
scanf_s
函数与scanf
函数相同,只是%c
、%s
和%[
转换说明符各需要两个参数(通常的指针和一个类型为rsize_t
的值,表示接收数组的大小,当使用%c
读取单个字符时,大小可能为1)。
您的代码没有提供接收数组的大小,而变量name
是指向数组第一个字符的指针,因此它包含name[0]
的地址。因此,在scanf_s
中,您的第一个参数name
是正确的,因为name
是一个指针,还要注意的是,对于第二个参数,您不能插入指针的大小,如sizeof(name)
,因为它始终相同。您需要指定您的char数组的大小(name[64]
),因此,对于第二个参数,您应该插入sizeof(name[64])
或64*sizeof(char)
。
您可以按以下方式更正您的代码:
char name[64];
if (scanf_s("%s", name, sizeof(name[64])) == 1)
printf("Your name is %s\n", name);
sizeof(name[64])
should be sizeof(name)
- yes这是一段对我来说很好用的代码:
char name[64];
scanf_s("%63s", name,(unsigned)_countof(name));
printf("Your name is %s", name);
此致敬礼
你应该这样做:scanf ("%63s", name);
更新:
以下代码对我有效:
#include <stdio.h>
int main(void) {
char name[64];
scanf ("%63s", name);
printf("Your name is %s", name);
return 0;
}
如果您正在使用Visual Studio,
请前往项目属性 -> 配置属性 -> C/C++-> 预处理器 -> 预处理器定义
,点击编辑
并添加_CRT_SECURE_NO_WARNINGS
,然后点击确定,应用设置并重新运行。
注意:这仅适用于做作业或类似情况,不建议在生产环境中使用。
#include<stdio.h>
int main()
{
char name[64];
printf("Enter your name: ");
scanf("%s", name);
printf("Your name is %s\n", name);
return 0;
}
&name
上的 &
没有任何影响,但是也不是必需的。可以省略它,因为你理解数组和指针之间的关系。如果你不理解这个关系,请先阅读相关资料,然后省略掉额外的 &
。 - dmckee --- ex-moderator kittenchar name[64];
),符号&name
生成一个char (*)[64]
。%s
格式期望一个char *
,而简单地引用name
会产生一个char *
。正如您所看到的,这两种类型是非常不同的。不幸的是,作为void *
查看的&name
的值与作为void *
查看的name
的值相同。这使得scanf("%63s", &name)
可以“工作”,但并不能阻止它是不正确的事实。 - Jonathan Leffler#include<stdio.h>
int main()
{
char name[64];
printf("Enter your name: ");
gets(name);
printf("Your name is %s\n", name);
return 0;
}
scanf
需要您提供缓冲区的长度。 - user3386109scanf()
代替scanf_s()
。或者更好的选择是使用fgets()
。 - Crowmanscanf
函数,必须指定长度以避免缓冲区溢出:scanf("%63s", name);
- M.M