2

これは私の最初の投稿であり、認めざるを得ません。プログラミングがひどいです。私はクラスのその男であり、彼の尻尾を切り落としていますが、他のクラスメートと同様にプログラミングを理解しているようには見えません。よろしくお願いします。以下で私の問題を説明しようと思います。

次のコード(コメントは削除されています)がありますが、実行すると、以下のような警告が表示されます。また、プログラムを実行すると、最初のユーザー入力値が許可されますが、突然、プログラムの最後にジャンプし、他の変数(変数「ベータ」など)の値を入力できなくなります。 )。出力の画像(http://i.stack.imgur.com/yc3jq.jpg)があり、アルファを入力したことがわかりますが、プログラムは最後まで実行されます。何かご意見は?

どうもありがとうございました!-スペンサー

- - - - - - - - - - - - - - -コード - - - - - - - -

    #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

コンパイラがあなたに言っているのは、Microsoftはscanfそれは安全ではないと考えているということです。

注意すれば安全に使用できますscanf。数値入力に問題があります(オーバーフローの動作は未定義です)が、これらの問題は修正されませんscanfscanf_s

scanf_sもともとはMicrosoft固有の拡張機能でした。これは、2011 ISO C標準( N1570 Annex K)のオプション機能として追加されました。多くのC実装はまだを提供していませんscanf_s

Cドラフト標準の引用:

K.3.5.3.4p4:

scanf_s関数は、scanf_s の引数の前に引数stdinが挿入されたfscanf_sと同等です。

K.3.5.3.2p4:

fscanf_s関数はfscanfと同等ですが、cs、および[変換指定子が引数のペアに適用される点が異なります(割り当ての抑制が*で示されている場合を除く )。これらの引数の最初の引数は、 fscanfの場合と同じです。その引数の直後に、引数リストで2番目の引数が続きます。2番目の引数は rsize_t型であり、ペアの最初の引数が指す配列内の要素の数を示します。最初の引数がスカラーオブジェクトを指している場合、それは1つの要素の配列であると見なされます。

scanf_sこの特定のプログラムではなくを使用scanfすると、安全性は低下しますが、移植性が低下します。

警告を使用_CRT_SECURE_NO_WARNINGSして無視します。

于 2013-12-09T16:46:12.623 に答える
2

コンパイラがここであなたに言っていることは、関数scanfが安全ではないということです。scanf悪用されると、システムが危険にさらされる可能性があるバグがあります(バッファオーバーフロー攻撃と呼ばれます)。scanf簡単に言うと、バグは、入力用に読み取るバイト数がわからないことです。したがってscanf、入力の読み取りが完了するまで「信じる」まで読み取ります。char配列では、この終わりは通常null文字'\0'です。ただし、'\0'文字列をscanf省略した場合は、そのバイトが見つかるまで読み取りを続行します。通常はscanf、独自の仮想メモリ空​​間の外側にあるメモリ位置に到達します。このアクションにより、OSはプログラムにセグメンテーションフォールト(セグメンテーションフォールト)を送信し、プログラムの存在を一時的に終了します。

新しい関数、scanf_s_s安全のために)を使用すると、入力の最大サイズを決定できます。これを使用して、バッファオーバーフロー攻撃をより効果的に防ぐことができます。これがHW割り当ての場合は、そのように見えますが、そのままにしておくことができます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 に答える