2012-04-03 49 views
2

這是我的第一篇文章,我不得不承認,編程時我很糟糕。我是班上的那個人,儘管他的尾巴已經消失,但似乎永遠無法掌握編程以及其他同學。所以請保持好心情,我會盡力在下面解釋我的問題。Scanf_s警告?跳過用戶輸入(主題:龍格庫塔,流行模擬)

我有下面的代碼(評論刪除),但是當我運行它時,我收到類似於下面列出的警告。另外,當我運行程序時,第一個用戶輸入的值是允許的,但是突然之間,它跳轉到程序結束,不允許我輸入其他變量的值(例如變量「beta」 )。我有一個輸出圖像(http://i.stack.imgur.com/yc3jq.jpg),你可以看到我輸入了alpha,但是程序運行到最後。有什麼想法嗎?

非常感謝您的幫助! -Spencer

----------------------------- CODE ------------- ---

#include<stdio.h> 
#include<stdlib.h> 
#include<math.h> 

float alpha, beta, h; 
float slope_k (float, float, float, float); 
float slope_q (float, float, float, float); 
float slope_p (float, float, float, float); 

int main (void) 
{ 

float t0=0, tf, h, S0, I0, R0, k1, k2, k3, k4, q1, q2, q3, q4, p1, p2, p3, p4; 
int N; 
char sim_file[1000]; 
FILE *out_file; 
float *time_out, *s_out, *i_out, *r_out; 

printf("Enter the value of the rate constant for infection (alpha) \n"); 
scanf("&f", &alpha); 

printf("Enter the value of the rate constant for recovery or death (beta) \n"); 
scanf("&f", &beta); 

printf("Enter the value of number of persons susceptible to the given contagion [S] at the initial time zero [i.e. S(t)=S(0) = ? ] \n"); 
scanf("&f", &S0); 

printf("Enter the value of the number of persons infected [I] at the intial time zero [i.e. I(t) = I(0) = ?] \n"); 
scanf("&f", &I0); 

printf("Enter the value of the number of persons that have already been infected but have recovered [or died] [R] at the initial time zero [i.e. R(t) = R(0) = ?] \n"); 
scanf("&f", &R0); 

printf("Enter the final time for solution \n"); 
scanf("&f", &tf); 

printf("Enter the solution step size (H) \n"); 
scanf("&f", &h); 

N = (int)(tf/h); 

printf("Enter file solution to store solution to simulation \n"); 
scanf("&s", sim_file); 

out_file = fopen(sim_file, "w"); 

time_out = (float *)calloc(sizeof(float), N); 
s_out = (float *)calloc(sizeof(float), N); 
i_out = (float *)calloc(sizeof(float), N); 
r_out = (float *)calloc(sizeof(float), N); 


time_out[0]= 0; 
s_out[0] = S0; 
i_out[0] = I0; 
r_out[0] = R0; 

for(int i = 0; i < N; ++i); 
{ 
int i = 0; 
time_out[i+1] = (i+1)*h; 

k1 = h*slope_k(time_out[i], s_out[i], i_out[i], r_out[i]); 
q1 = h*slope_q(time_out[i], s_out[i], i_out[i], r_out[i]); 
p1 = h*slope_p(time_out[i], s_out[i], i_out[i], r_out[i]); 

k2 = h*slope_k(time_out[i]+(h/2), s_out[i]+(k1/2), i_out[i]+(q1/2), r_out[i]+(p1/2)); 
q2 = h*slope_q(time_out[i]+(h/2), s_out[i]+(k1/2), i_out[i]+(q1/2), r_out[i]+(p1/2)); 
p2 = h*slope_p(time_out[i]+(h/2), s_out[i]+(k1/2), i_out[i]+(q1/2), r_out[i]+(p1/2)); 

k3 = h*slope_k(time_out[i]+(h/2), s_out[i]+(k2/2), i_out[i]+(q2/2), r_out[i]+(p2/2)); 
q3 = h*slope_q(time_out[i]+(h/2), s_out[i]+(k2/2), i_out[i]+(q2/2), r_out[i]+(p2/2)); 
p3 = h*slope_p(time_out[i]+(h/2), s_out[i]+(k2/2), i_out[i]+(q2/2), r_out[i]+(p2/2)); 

k4 = h*slope_k((time_out[i] + h), (s_out[i]+k3), (i_out[i]+q3), (r_out[i]+p3)); 
q4 = h*slope_q((time_out[i] + h), (s_out[i]+k3), (i_out[i]+q3), (r_out[i]+p3)); 
p4 = h*slope_p((time_out[i] + h), (s_out[i]+k3), (i_out[i]+q3), (r_out[i]+p3)); 

s_out[i+1] = s_out[i] + (1.0/6)*(k1 + (2*k2) + (2*k3) + k4); 
i_out[i+1] = i_out[i] + (1.0/6)*(q1 + (2*q2) + (2*q3) + q4); 
r_out[i+1] = r_out[i] + (1.0/6)*(p1 + (2*p2) + (2*p3) + p4); 

} 

return 0; 
} 

float slope_k(float t, float s, float i, float r) 
{ 
float slope_k_out; 
slope_k_out = -alpha*s*i; 
return slope_k_out; 
} 

float slope_q(float t, float s, float i, float r) 
{ 
float slope_q_out; 
slope_q_out = (alpha*s*i)-(beta*i); 
return slope_q_out; 
} 

float slope_p(float t, float s, float i, float r) 
{ 
float slope_p_out; 
slope_p_out = beta*i; 
return slope_p_out; 
} 

例警告:

warning C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. 

回答

2

什麼編譯器在這裏告訴你的是,該功能scanf是不是安全。 scanf有一個錯誤,如果被利用,可能會導致系統受到攻擊(稱爲緩衝區溢出攻擊)。簡而言之,這個錯誤是一個人不會告訴scanf要輸入多少個字節。因此scanf將會讀取,直到它「完全」讀完輸入。在一個char數組中,這個結尾通常是空字符'\0'。但是,如果從字符串中除去'\0',則scanf將繼續讀取,直至找到該字節 - 通常,scanf將到達其自己的虛擬內存空間之外的內存位置。此操作將導致操作系統向您的程序發送一個分段錯誤(seg fault),該錯誤一般會結束程序的存在。

更新的函數scanf_s_s用於安全)可讓您確定輸入的最大大小,您可以使用該大小更有效地防止緩衝區溢出攻擊。如果這是HW分配,它看起來就是這樣,您可以在那裏離開scanf。但是,要擺脫compilier警告並嘗試成爲更好的程序員,請修復它!使用sscanf_s並有一個全局變量(或其他...)來確定最大輸入大小(例如int SCANF_INPUT_SIZE = 1000)。

祝你好運!

編輯 - 將那些"&f"更改爲"%f"這就是錯誤!

0

scanf函數讀取值到內存中,如果你正在閱讀的價值比你給它的內存(通常只有一個較長的問題與字符串)它可能覆蓋一些其他內存並導致錯誤或病毒

scanf_s是一個新版本,您可以告訴函數需要讀取的最大內存。

如果這是隻有你或受信任的用戶將只使用功課碼 - 別擔心

+0

謝謝你!我意識到它與scanf_s無關。我爲「%f」放了一個&而不是%!哎呀! – user1309448 2012-04-03 04:16:54

4

什麼編譯器告訴你的是微軟認爲scanf是不安全的。

scanf功能可以如果您小心使用可以安全使用。 scanf確實有數字輸入問題(溢出具有未定義的行爲),但scanf_s不能解決這些問題

scanf_s最初是Microsoft特定的擴展;它被添加爲2011 ISO C標準(N1570附件K)的可選功能。許多C實現仍然不提供scanf_s

引用標準C草案:

K.3.5.3.4p4:

scanf_s函數等效於fscanf_s用參數標準輸入 參數之前插入到scanf_s

K.3.5.3.2p4:

fscanf_s函數等效於的fscanf除了Ç小號, 和[轉換說明適用於一對參數(除非 分配抑制由 表示*)。這些論點中的第一個與fscanf相同。該參數緊接在參數列表中,第二個 參數的類型爲rsize_t,並給出該對的第一個參數指向的數組 中的元素數。如果第一個參數指向標量對象,則它被認爲是一個元素的數組。

使用scanf_s而不是scanf這個特定程序使得沒有安全,但導致其便攜性較差。

使用_CRT_SECURE_NO_WARNINGS並忽略警告。