gpt4 book ai didi

c - scanf_s 中的访问冲突

转载 作者:太空宇宙 更新时间:2023-11-04 01:46:26 24 4
gpt4 key购买 nike

我正在尝试制作一个程序,看看我可以用 C 中的结构做什么。但是在 scanf_s("%s", &user.name) 的主函数中出现错误:

Exception thrown at 0x5C26D3EC (ucrtbased.dll) in StructureTest.exe:

0xC0000005: Access violation writing location 0x01341000. occurred

我也得到一些compiler warnings .这是我的代码:

#include <stdio.h>

struct birthdate {
int day;
char month[9];
int year;
};

typedef struct birthdate dob;
struct info {
char name[40];
dob birthdate;
int age;
char sex[6];
char *origin;
};
void printinfo(struct info user) {
printf("---- User Data ----\n");
printf("Name: %s\n", user.name);
printf("Date of birth: %d/%s/%d\n", user.birthdate.day,
user.birthdate.month, user.birthdate.year);
printf("Age: %d\n", user.age);
printf("Sex: %s\n", user.sex);
printf("Country of origin: %s", user.origin);
}

int main() {
printf("--Please enter your info--\n");
struct info user;
printf("Please enter your name: ");
scanf_s("%s", &user.name); // <-- exception thrown here
printf("Please enter your date of birth in the format (dd/mm/yyyy): ");
scanf_s("%d %s %d", &user.birthdate.day, &user.birthdate.month,
&user.birthdate.year);
printf("Please enter your age: ");
scanf_s("%d", &user.age);
printf("Please enter your gender ([M]ale/[F]emale): ");
scanf_s("%s", &user.sex);
printf("Please enter your country of origin: ");
scanf_s("%s", &user.origin); // <- Another exception thrown here

printf("\n\n");
printinfo(user);

printf("\nPress ENTER to continue..");
getchar();
return 0;
}

我对结构还没有真正的经验,但我怀疑它可能与数组和指针有关,而且我写的名字无处可去。

最佳答案

您没有显示您提供给程序的输入。

你的程序有一些小错误和一些大错误:

  • 首先,你对char的分配太紧了。阵列。例如,month birthdate 中的字段struct 只有 9 个空间来存储月份,这意味着你不能像 september 那样存储月份。这需要 9 个字符加上一个 \0字符串末尾的 nul 字符。如果你不小心,这可能是你执行的问题。

  • 通过 struct 是不常见的做法s 直接按值 到一个函数,因为这使得编译器将完整的结构内容复制到参数堆栈中。更常见的是通过引用传递结构,如

      void printinfo(struct info *user);

    然后称它为

      printinfo(&user);

    这使得编译器只传递一个指向结构的指针,节省时间和内存。

我还没有找到 scanf_s我的在线手册中的功能,你从哪里得到的?好吧,经过一些挖掘,我发现了它们......从这些功能的 VC 手册中(不是标准的,只是 Microsoft 的扩展):

Unlike scanf and wscanf, scanf_s and wscanf_s require the buffer size to be specified for all input parameters of type c, C, s, S, or string control sets that are enclosed in []. The buffer size in characters is passed as an additional parameter immediately following the pointer to the buffer or variable...

所以你必须使用

scanf_s("%s", &user.name, sizeof user.name - 1);

对于您正在阅读的其他字符串也是如此。

注意

那些_s带后缀的函数只是 Microsoft 对其编译器的扩展。它们不可移植(无论如何也不是标准的)并且不会出现在大多数 C 实现中。最好不要使用它们,除非您打算只使用 Microsoft C 编译器(并且您不保证它们将来会消失)。除了使用非标准函数之外,还有其他检查缓冲区大小的方法,例如

scanf("%.39s", user.name); /* there's no need to use the & operator here */

(如果您需要将尺寸作为参数传递,您可以执行以下操作):

SCANF("%.*s", sizeof user.name - 1, user.name);

将完成工作,或者

fgets(user.name, sizeof user.name, stdin);

(此调用要求您从字符串中删除最后一个 \n)这两个调用都是标准的,包含在 <stdio.h> 中.

关于c - scanf_s 中的访问冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53036713/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com