2012-04-03 2 views
2

Это мой первый пост, и я должен признать, что я ужасен в программировании. Я тот парень в классе, который работает с его хвостом, но никогда не может понять, как программировать, так и остальных моих одноклассников. Поэтому, пожалуйста, будьте добрыми, я попытаюсь объяснить мою проблему ниже.Предупреждение Scanf_s? Пропускает пользовательские входы (темы: Runge-Kutta, Эпидемическое моделирование)

У меня есть следующий код (комментарии удалены), но когда я его запускаю, появляется предупреждение, подобное приведенному ниже. Кроме того, когда я запускаю программу, первое введенное пользователем значение допускается, но затем внезапно он переходит в конец программы, не позволяя мне вводить значения для других переменных (например, переменная «бета»,). У меня есть изображение вывода (http://i.stack.imgur.com/yc3jq.jpg), и вы можете видеть, что я вхожу в альфа, но тогда программа работает до конца. Есть предположения?

Спасибо вам большое за вашу помощь! -Spencer

----------------------------- КОД -------------- ---

#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 будет читать до тех пор, пока «верит», это делается с чтением ввода. В массиве символов этот конец обычно является нулевым символом '\0'. Однако, если вы покинете '\0' из строки, scanf продолжит чтение до тех пор, пока не найдет, что байт - обычно scanf достигнет места памяти, находящегося вне своего виртуального пространства памяти. Это действие приведет к тому, что ОС отправит вашей программе ошибку сегментации (seg fault), которая в конечном итоге закончит существование вашей программы.

Более новая функция, scanf_s, (_s для обеспечения безопасности), позволяет определить максимальный размер ввода, который вы можете использовать для более эффективного предотвращения атак переполнения буфера. Если это для назначения HW, которое, похоже, оно есть, вы можете оставить там scanf. Однако, чтобы избавиться от предупреждения компилятора И попытайтесь стать лучшим программистом, исправьте его! Используйте sscanf_s и получите глобальную переменную (или что-то ...), которая определяет максимальный размер ввода (например, int SCANF_INPUT_SIZE = 1000).

Удачи вам!

EDIT - Измените те "&f" на "%f". Это ошибка!

0

зсапЕ считывает значение в памяти, если значение, которое вы читаете больше, чем память вы даете его (как правило, только проблема со строками) он может перезаписать некоторую другую память и привести к ошибке или вирусу

scanf_s - это новая версия, где вы указываете функции максимальной памяти для чтения.

Если это только домашнее задание код, который только вы или доверенный пользователь собирается использовать - don'tworry

+0

спасибо, человек! Я понял, что это не имеет никакого отношения к scanf_s. Я положил & вместо% для «% f»! упс! – user1309448

4

Что компилятор вам говорит, это Microsoft считает, что не scanf небезопасен.

Функция scanfможет быть использована безопасно, если вы будете осторожны. scanf имеет проблемы с числовым вводом (переполнение имеет неопределенное поведение), но scanf_sне устраняет эти проблемы.

scanf_s Первоначально был расширением Microsoft; он был добавлен в качестве дополнительной функции к стандарту ISO ISO 2011 (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 и игнорируйте предупреждение.

Смежные вопросы