scanf_s抛出异常

时间:2010-02-28 11:10:49

标签: windows exception visual-c++

为什么以下代码在输入要放入结构的数字后到达第二个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);

...

5 个答案:

答案 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将被解释为指针,这很可能会使程序崩溃。