2

这是我的第一篇文章,我不得不承认,我在编程方面很糟糕。我是班上那个拼命工作的人,但似乎永远无法像其他同学一样掌握编程。所以请友善,我将在下面尝试解释我的问题。

我有以下代码(已删除注释),但是当我运行它时,我收到类似于下面列出的警告。另外,当我运行程序时,允许第一个用户输入的值,但突然之间,它跳到程序的末尾,不允许我输入其他变量的值(例如变量“beta” )。我有输出图像(http://i.stack.imgur.com/yc3jq.jpg),您可以看到我输入了 alpha,但随后程序运行到最后。有什么想法吗?

非常感谢您的帮助!-斯宾塞

- - - - - - - - - - - - - - -代码 - - - - - - - -

    #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.
4

3 回答 3

5

编译器告诉你的是微软认为scanf是不安全的。

如果您小心,可以安全地使用功能scanf。数字输入确实存在问题(溢出具有未定义的行为),但不能解决这些问题scanfscanf_s

scanf_s最初是 Microsoft 特定的扩展;它作为可选功能添加到 2011 ISO C 标准(N1570附录 K)中。许多 C 实现仍然不提供scanf_s.

引用 C 草案标准:

K.3.5.3.4p4:

scanf_s函数等效于fscanf_s,其中参数stdin 插入到scanf_s的参数之前

K.3.5.3.2p4:

fscanf_s函数等效于fscanf,除了cs[转换说明符适用于一对参数(除非分配抑制由 *指示)。这些参数中的第一个与fscanf相同。该参数在参数列表中紧跟第二个参数,其类型为 rsize_t,并给出数组中由该对的第一个参数指向的元素的数量。如果第一个参数指向一个标量对象,它被认为是一个元素的数组。

使用scanf_s而不是scanf用于这个特定的程序会使其不安全,但会导致它的可移植性降低。

使用_CRT_SECURE_NO_WARNINGS并忽略警告。

于 2013-12-09T16:46:12.623 回答
2

编译器在这里告诉您的是该函数scanf不安全。scanf有一个漏洞,如果被利用,可能会导致系统受到威胁(称为缓冲区溢出攻击)。简而言之,错误在于不知道scanf要为输入读取多少字节。因此scanf将一直读取,直到它“相信”它已完成读取输入。在 char 数组中,这一端通常是空字符'\0'。但是,如果一个人离开了'\0'一个字符串,scanf它将继续读取,直到找到该字节——通常,scanf将到达它自己的虚拟内存空间之外的内存位置。此操作将导致操作系统向您的程序发送分段错误(seg fault),这将结束您的程序的存在。

较新的函数 , scanf_s(_s表示安全) 可让您确定输入的最大大小,您可以使用它来更有效地防止缓冲区溢出攻击。如果这是一个硬件任务,看起来就是这样,你可以离开scanf那里。但是,要摆脱编译器警告并尝试成为更好的程序员,请修复它!使用sscanf_s并拥有一个确定最大输入大小(例如 int )的全局变量(或其他东西...... SCANF_INPUT_SIZE = 1000)。

祝你好运!

编辑 - 将这些更改"&f""%f"错误!

于 2012-04-03T04:03:56.457 回答
0

scanf 将一个值读入内存,如果您正在读取的值比您给它的内存长(通常只是字符串问题),它可能会覆盖其他一些内存并导致错误或病毒

scanf_s 是一个新版本,您可以在其中告诉函数要读取的最大内存。

如果这只是只有您或受信任的用户才会使用的作业代码 - 不要担心

于 2012-04-03T03:44:22.053 回答