Scanf_s warning? Skips User Inputs (topics: Runge-Kutta, Epidemic Simulation)

感情迁移 提交于 2019-12-04 04:52:25

问题


This is my first post and I have to admit, I am terrible at programming. I am that guy in the class that works his tail off, but can never seem to grasp programming as well as the rest of my classmates. So please be nice, I will try to explain my problem below.

I have the following code (comments removed), but when I run it I get a warning similar to the one listed below. Also, when I run the program, the first user inputted value is allowed, but then all of the sudden, it jumps to the end of the program, not allowing me to input the values for the other variables (e.g. the variable "beta"). I have an image of the output (http://i.stack.imgur.com/yc3jq.jpg) and you can see that I enter alpha, but then the program runs to the end. Any thoughts?

Thank You so very much for your help! -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;
}

Example warning:

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.

回答1:


What the compiler is telling you here is that the function scanf is not safe. scanf has a bug that, if exploited, can cause a system to become compromised (called a buffer overflow attack). In brief, the bug is that one does not tell scanf how many bytes to read for input. Thus scanf will read until it "believes" it is done reading the input. In a char array, this end is usually the null character '\0'. However, if one leaves off '\0' from a string, scanf will continue reading until it finds that byte -- usually, scanf will reach a memory location that is outside of its own virtual memory space. This action will cause the OS to send your program a segmentation fault (seg fault) which will summarily end your program's existence.

The newer function, scanf_s,(_s for secure), lets you determine the max size of the input, which you can use to more effectively prevent buffer overflow attacks. If this is for a HW assignment, which it looks like it is, you can leave scanf there. However, to get rid of the compilier warning AND try and become a better programmer, fix it! Use sscanf_s and have a global variable (or something...) that determines maximum input size (e.g. int SCANF_INPUT_SIZE = 1000 ).

Good luck!

EDIT -- Change those "&f" to "%f" that's the error!




回答2:


What the compiler is telling you is that Microsoft thinks that scanf is not safe.

The scanf function can be used safely if you're careful. scanf does have problems with numeric input (overflow has undefined behavior), but scanf_s doesn't fix those problems.

scanf_s was originally a Microsoft-specific extension; it was added as an optional feature to the 2011 ISO C standard (N1570 Annex K). Many C implementations still don't provide scanf_s.

Quoting the C draft standard:

K.3.5.3.4p4:

The scanf_s function is equivalent to fscanf_s with the argument stdin interposed before the arguments to scanf_s.

K.3.5.3.2p4:

The fscanf_s function is equivalent to fscanf except that the c, s, and [ conversion specifiers apply to a pair of arguments (unless assignment suppression is indicated by a *). The first of these arguments is the same as for fscanf. That argument is immediately followed in the argument list by the second argument, which has type rsize_t and gives the number of elements in the array pointed to by the first argument of the pair. If the first argument points to a scalar object, it is considered to be an array of one element.

Using scanf_s rather than scanf for this particular program makes it no safer, but causes it to be less portable.

Use _CRT_SECURE_NO_WARNINGS and ignore the warning.




回答3:


scanf reads a value into memory,if the value you are reading is longer than the memory you are giving it ( typically only a problem with strings) it could overwrite some other memory and lead to a bug or a virus

scanf_s is a new version where you tell the function the maximum memory to read.

If this is only homework code that only you or a trusted user is going to use - don'tworry



来源:https://stackoverflow.com/questions/9986776/scanf-s-warning-skips-user-inputs-topics-runge-kutta-epidemic-simulation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!