问题
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