为什么以下代码在输入要放入结构的数字后到达第二个scanf_s
时会抛出异常。
这绝不代表完整的链表实现。
输入值时,不确定如何进入下一个scanf_s
?有什么想法吗?
编辑:使用建议的解决方案更新了代码,但在第一次AccessViolationException
之后仍然获得了scanf_s
代码:
struct node
{
char name[20];
int age;
float height;
node *nxt;
};
int FillInLinkedList(node* temp)
{
int result;
temp = new node;
printf("Please enter name of the person");
result = scanf_s("%s", temp->name);
printf("Please enter persons age");
result = scanf_s("%d", &temp->age); // Exception here...
printf("Please enter persons height");
result = scanf_s("%f", &temp->height);
temp->nxt = NULL;
if (result >0)
return 1;
else return 0;
}
// calling code
int main(array<System::String ^> ^args)
{
node temp;
FillInLinkedList(&temp);
...
答案 0 :(得分:5)
您使用的scanf_s参数不正确。请查看函数MSDN documentation中的示例。它要求您在缓冲区之后为所有字符串或字符参数传递缓冲区的大小。所以
result = scanf_s("%s", temp->name);
应该是:
result = scanf_s("%s", temp->name, 20);
对scanf_s的第一次调用是从堆栈读取垃圾,因为它正在寻找另一个参数并可能破坏内存。
没有编译器错误,因为scanf_s使用变量参数列表 - 该函数没有固定数量的参数,因此编译器不知道scanf_s期望什么。
答案 1 :(得分:3)
你需要
result = scanf_s("%d", &temp->age);
和
result = scanf_s("%f", &temp->height);
原因是sscanf
(和朋友)需要指针到输出变量,因此它可以将结果存储在那里。
顺便说一下,你的函数参数temp
也有类似的问题。由于您正在更改指针(而不仅仅是指向它的内容),因此您需要传递一个双指针,以便在您的函数外部显示更改:
int FillInLinkedList(node** temp)
当然,你必须在函数内部进行必要的更改。
答案 2 :(得分:2)
scanf()将数据存储到变量中,因此需要传递变量的地址(或其指针)。例如:
char string[10];
int n;
scanf("%s", string); //string actually points to address of
//first element of string array
scanf("%d", &n); // &n is the address of the variable 'n'
答案 3 :(得分:1)
%19c
应为%s
temp->age
应为&temp-age
temp->height
应为&temp->height
您的编译器应该警告您 关于这些错误
答案 4 :(得分:1)
我认为你需要通过地址将参数传递给scanf()函数。即&amp; temp-&gt; age
否则temp-age将被解释为指针,这很可能会使程序崩溃。