views:

87

answers:

5

Why does the following code throw an exception when getting to the second scanf_s after entering an number to put into the struct.

This by no means represents a complete linked list implementation.

Not sure how to get onto the next scanf_s when having entered the value? Any ideas?

EDIT: Updated code with suggested solution, but still get an AccessViolationException after first scanf_s

Code:

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);

...
+1  A: 
  • %19c should be %s

  • temp->age should be &temp-age

  • temp->height should be &temp->height

  • Your compiler should be warning you about these errors

Paul R
I changed it and it still gives me an AccessViolationException...
Tony
Did you make all 3 of the above changes ?
Paul R
made all changes to no effect...
Tony
When you test are you entering less than 20 characters for the name ?
Paul R
+1  A: 

I believe you need to pass parameters to scanf() functions by address. i.e. &temp->age

otherwise temp-age will be interpreted as a pointer, which will most likely crash your program.

Ferruccio
+2  A: 

You need

result = scanf_s("%d", &temp->age);

and

result = scanf_s("%f", &temp->height);

Reason is that sscanf (and friends) requires a pointer to the output variable so it can store the result there.

BTW, you have a similar problem with the parameter temp of your function. Since you're changing the pointer (and not just the contents of what it points to), you need to pass a double pointer so that the changes will be visible outside your function:

int FillInLinkedList(node** temp)

And then of course you'll have to make the necessary changes inside the function.

Martin B
@Martin: Funny you mention pointer to pointers, that's the whole reason I was attempting to write this, is to learn about pointers to pointers, seems I haven't fully got the idea yet...
Tony
@Tony: Take a look at this question -- the highest voted answer has quite a good description: http://stackoverflow.com/questions/897366/how-do-pointer-to-pointers-work-in-c
Martin B
+2  A: 
N 1.1
+1  A: 

You are using scanf_s with incorrect parameters. Take a look at the examples in the MSDN documentation for the function. It requires that you pass in the size of the buffer after the buffer for all string or character parameters. So

result = scanf_s("%s", temp->name); 

should be:

 result = scanf_s("%s", temp->name, 20);

The first call to scanf_s is reading garbage off the stack because it is looking for another parameter and possibly corrupting memory.

There is no compiler error because scanf_s uses a variable argument list - the function doesn't have a fixed number of parameters so the compiler has no idea what scanf_s is expecting.

shf301