2010-02-28 228 views
3

爲什麼下面的代碼輸入一個號碼放入該結構後獲得的第二scanf_s時拋出異常。scanf_s拋出異常

這絕不代表一個完整的鏈接列表實現。

不知道如何進入下一個scanf_s當輸入值?有任何想法嗎?

編輯:更新後的代碼與建議的解決方案,但仍獲得第一scanf_s

代碼後AccessViolationException

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

你正在使用託管代碼,你爲什麼搞亂scanf()?使用Console :: ReadLine(),int :: TryParse()和List 。 – 2010-02-28 12:07:23

回答

3

你需要

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

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

原因是sscanf(朋友)需要一個指針到輸出變量,因此可以把結果存儲在那裏。

順便說一句,你有一個類似的問題,你的函數參數temp。既然你改變指針(而不是它所指向的只是內容),你需要通過一個雙指針,這樣的變化將是你的函數外部可見:

int FillInLinkedList(node** temp) 

然後當然你「將不得不作出在函數內部進行必要的修改。

+0

@Martin:有趣的是你提到指針的指針,這就是我試圖寫這個的全部原因,就是要學習指針的指針,似乎我還沒有完全想到這個想法...... – 2010-02-28 11:19:38

+0

@Tony:看一看在這個問題 - 最高投票答案有一個很好的描述:http://stackoverflow.com/questions/897366/how-do-pointer-to-pointers-work-in-c – 2010-02-28 16:30:14

1
  • %19c應該%s

  • temp->age應該是&temp-age

  • temp->height應該&temp->height

  • 你的編譯器應該警告你 這些錯誤

+0

我改變了它,它仍然給我一個AccessViolationException ... – 2010-02-28 11:15:41

+0

你做了所有3個上述改變? – 2010-02-28 11:19:44

+0

作出所有更改不起作用... – 2010-02-28 11:30:58

1

我相信你需要按地址傳遞參數給scanf()函數。即& temp-> age

否則temp-age將被解釋爲一個指針,這很可能會導致程序崩潰。

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' 
5

您正在使用不正確的參數scanf_s。看看在MSDN documentation該函數的例子。它需要你在緩衝區的大小通過緩衝所有字符串或字符參數後。所以

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

應該是:

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

第一次調用scanf_s是閱讀垃圾出棧,因爲它正在尋找其他參數和可能損壞內存。

沒有編譯器錯誤,因爲scanf_s使用變量參數列表 - 函數沒有固定數量的參數,所以編譯器不知道scanf_s期望的是什麼。

+0

微軟的一個可怕的決定。 – this 2013-12-29 23:57:10

+0

在%s中包含一個寬度說明符也是很好的做法。 scanf_s(「%19s」,temp-> name,20); – curlyhairedgenius 2017-11-07 19:29:23