途中まで書いたのですがエラーがあり、もう少し簡単なコードもあるのではないかと思ってます。
問題文はこちらです。
寄付金の数量を更新する。システムは、従業員が特定の寄付を選択し、受領済みまたは分配済みの数量を示すことができるようにする必要があります。どちらの場合でも、選択された寄付の数量はdonation.txtファイルでそれに応じて更新される必要があります。
例:donation.txt ファイルにあるフェイスマスクの初期数量が100万個であるとします。社会が新しい在庫を受け取った場合、この数量はdonation.txtファイル内の既存の数量100万に追加されなければならない。また、病院への配付の場合は、donation.txt の数量から配付数量を差し引きます。
注:病院に寄付を配布する場合、寄付のコードと配布数をdist.txtという名前のテキストファイルに記録する必要があります。また、各寄付は病院間で共有することができます。
私の書いたコードはこちらなんですが、間違えているところともっといいやり方があれば教えてください。お願いします。
void Received() {
FILE *fp;
fp = fopen("donation.txt", "r+");
struct quantity;
char SupplyCode[6];
char amount[1];
printf("Choose from CT, HS, FM, SM, OM:");
scanf("%s", SupplyCode);
printf("How many do you get:");
scanf("%s", amount);
switch (SupplyCode) {
case 1:
if (strcmp(SupplyCode, "CT") == 0)
quantity.CT = quantity.CT + amount;
break;
case 2:
if (strcmp(SupplyCode, "HS") == 0)
qa.HS = qa.HS + amount;
break;
case 3:
if (strcmp(SupplyCode, "FM") == 0)
qa.FM = qa.FM + amount;
break;
case 4:
if (strcmp(SupplyCode, "SM") == 0)
qa.SM = qa.SM + amount;
break;
case 5:
if (strcmp(SupplyCode, "OM") == 0)
qa.OM = qa.OM + amount;
break;
}
}
void Distributed() {
FILE *fp;
fp = fopen("donation.txt", "r+");
char SupplyCode[6];
char amount;
struct quantity qa;
printf("Choose from CT, HS, FM, SM, OM:");
scanf("%s", SupplyCode);
printf("How many do you send:");
scanf("%s", amount);
switch (SupplyCode) {
case 1:
if (strcmp(SupplyCode, "CT") == 0)
qa.CT = qa.CT - amount;
break;
case 2:
if (strcmp(SupplyCode, "HS") == 0)
qa.HS = qa.HS - amount;
break;
case 3:
if (strcmp(SupplyCode, "FM") == 0)
qa.FM = qa.FM - amount;
break;
case 4:
if (strcmp(SupplyCode, "SM") == 0)
qa.SM = qa.SM - amount;
break;
case 5:
if (strcmp(SupplyCode, "OM") == 0)
qa.OM = qa.OM - amount;
break;
}
}
テキストファイルの在庫の更新
Re: テキストファイルの在庫の更新
ぴぴ さんが書きました: ↑1年前途中まで書いたのですがエラーがあり、もう少し簡単なコードもあるのではないかと思ってます。
問題文はこちらです。
寄付金の数量を更新する。システムは、従業員が特定の寄付を選択し、受領済みまたは分配済みの数量を示すことができるようにする必要があります。どちらの場合でも、選択された寄付の数量はdonation.txtファイルでそれに応じて更新される必要があります。
例:donation.txt ファイルにあるフェイスマスクの初期数量が100万個であるとします。社会が新しい在庫を受け取った場合、この数量はdonation.txtファイル内の既存の数量100万に追加されなければならない。また、病院への配付の場合は、donation.txt の数量から配付数量を差し引きます。
注:病院に寄付を配布する場合、寄付のコードと配布数をdist.txtという名前のテキストファイルに記録する必要があります。また、各寄付は病院間で共有することができます。
私の書いたコードはこちらなんですが、間違えているところともっといいやり方があれば教えてください。お願いします。
void Received() {
FILE *fp;
fp = fopen("donation.txt", "r+");
struct quantity qa;
char SupplyCode[6];
char amount[1];
printf("Choose from CT, HS, FM, SM, OM:");
scanf("%s", SupplyCode);
printf("How many do you get:");
scanf("%s", amount);
switch (SupplyCode) {
case 1:
if (strcmp(SupplyCode, "CT") == 0)
qa.CT = qa.CT + amount;
break;
case 2:
if (strcmp(SupplyCode, "HS") == 0)
qa.HS = qa.HS + amount;
break;
case 3:
if (strcmp(SupplyCode, "FM") == 0)
qa.FM = qa.FM + amount;
break;
case 4:
if (strcmp(SupplyCode, "SM") == 0)
qa.SM = qa.SM + amount;
break;
case 5:
if (strcmp(SupplyCode, "OM") == 0)
qa.OM = qa.OM + amount;
break;
}
}
void Distributed() {
FILE *fp;
fp = fopen("donation.txt", "r+");
char SupplyCode[6];
char amount;
struct quantity qa;
printf("Choose from CT, HS, FM, SM, OM:");
scanf("%s", SupplyCode);
printf("How many do you send:");
scanf("%s", amount);
switch (SupplyCode) {
case 1:
if (strcmp(SupplyCode, "CT") == 0)
qa.CT = qa.CT - amount;
break;
case 2:
if (strcmp(SupplyCode, "HS") == 0)
qa.HS = qa.HS - amount;
break;
case 3:
if (strcmp(SupplyCode, "FM") == 0)
qa.FM = qa.FM - amount;
break;
case 4:
if (strcmp(SupplyCode, "SM") == 0)
qa.SM = qa.SM - amount;
break;
case 5:
if (strcmp(SupplyCode, "OM") == 0)
qa.OM = qa.OM - amount;
break;
}
}
Re: テキストファイルの在庫の更新
東上☆海美☆「
> 途中まで書いたのですがエラーがあり、もう少し簡単なコードもあるのではないかと思ってます。
排他処理をすると、もっとコードが複雑になると思います。
」
> 途中まで書いたのですがエラーがあり、もう少し簡単なコードもあるのではないかと思ってます。
排他処理をすると、もっとコードが複雑になると思います。
」
VTuber:
東上☆海美☆(とうじょう・うみみ)
http://atassyu.php.xdomain.jp/vtuber/index.html
レスがついていないものを優先して、レスするみみ。時々、見当外れなレスしみみ。
中の人:
手提鞄あたッしュ、[MrAtassyu] 手提鞄屋魚有店
http://ameblo.jp/mratassyu/
Pixiv: 666303
Windows, Mac, Linux, Haiku, Raspbery Pi, Jetson Nano, 電子ブロック 持ち。
東上☆海美☆(とうじょう・うみみ)
http://atassyu.php.xdomain.jp/vtuber/index.html
レスがついていないものを優先して、レスするみみ。時々、見当外れなレスしみみ。
中の人:
手提鞄あたッしュ、[MrAtassyu] 手提鞄屋魚有店
http://ameblo.jp/mratassyu/
Pixiv: 666303
Windows, Mac, Linux, Haiku, Raspbery Pi, Jetson Nano, 電子ブロック 持ち。
Re: テキストファイルの在庫の更新
ソースコードを提示する際は、BBCodeが有効な(無効にしない)状態で、
BBCodeのcodeタグの開始タグと終了タグの組(開始タグが先)で囲んでいただけると、
見やすくてありがたいです。
・fopenしたファイルをfcloseしていない
・amountの処理が不適切
・switchの使い方が不適切
ですね。
fopenしたファイルをfcloseしていない
そのまんまです。
開いたファイルは閉じるべきです。
開いたファイルを閉じないと、書き込んだ内容が反映されない場合がある、
並行でファイルを開ける件数を使い切ってしまいファイルが開けなくなる、
などの問題が生じる可能性があります。
fopenが成功したか (返り値がNULLでないか) もチェックするとさらによいでしょう。
amountの処理が不適切
Received関数では となっていますが、これでは1文字以上の文字列が入力されると、
C言語では文字列は最後に終端を表すナル文字が追加されるため、
範囲外への書き込みが発生し、意図せずデータを破壊する原因となります。
また、Distributed関数では となっていますが、これは未初期化で不定のamountの値を
読み込んだ文字列を書き込む位置(ポインタ)としてscanf関数に渡すため、
文字列を読み込むとアクセス違反が生じる可能性が高いです。
1文字を読み込むには、書式%cを用います。 ただし、この後の処理を考えると、amountをint型にして書式%dで読み込むほうが自然と考えられます。 scanfの戻り値をチェックし、本当に読み込んだかどうか確認するとさらに良くなるでしょう。
switchの使い方が不適切
SupplyCode (配列 → 先頭要素へのポインタに変換される) をswitchに渡すのは意味が無いと考えられます。
この場合、switch文は削除し、strcmpの返り値による分岐をelse ifで繋げるのがいいでしょう。
BBCodeのcodeタグの開始タグと終了タグの組(開始タグが先)で囲んでいただけると、
見やすくてありがたいです。
とりあえずパッと見で致命的に間違っていると考えられるのはぴぴ さんが書きました: ↑1年前私の書いたコードはこちらなんですが、間違えているところともっといいやり方があれば教えてください。お願いします。
・fopenしたファイルをfcloseしていない
・amountの処理が不適切
・switchの使い方が不適切
ですね。
fopenしたファイルをfcloseしていない
そのまんまです。
開いたファイルは閉じるべきです。
開いたファイルを閉じないと、書き込んだ内容が反映されない場合がある、
並行でファイルを開ける件数を使い切ってしまいファイルが開けなくなる、
などの問題が生じる可能性があります。
fopenが成功したか (返り値がNULLでないか) もチェックするとさらによいでしょう。
amountの処理が不適切
Received関数では となっていますが、これでは1文字以上の文字列が入力されると、
C言語では文字列は最後に終端を表すナル文字が追加されるため、
範囲外への書き込みが発生し、意図せずデータを破壊する原因となります。
また、Distributed関数では となっていますが、これは未初期化で不定のamountの値を
読み込んだ文字列を書き込む位置(ポインタ)としてscanf関数に渡すため、
文字列を読み込むとアクセス違反が生じる可能性が高いです。
1文字を読み込むには、書式%cを用います。 ただし、この後の処理を考えると、amountをint型にして書式%dで読み込むほうが自然と考えられます。 scanfの戻り値をチェックし、本当に読み込んだかどうか確認するとさらに良くなるでしょう。
switchの使い方が不適切
SupplyCode (配列 → 先頭要素へのポインタに変換される) をswitchに渡すのは意味が無いと考えられます。
この場合、switch文は削除し、strcmpの返り値による分岐をelse ifで繋げるのがいいでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: テキストファイルの在庫の更新
関数の引数として(voidを書かずに)空文字列を指定していることから、このコードはC++でしょうか?
C言語の場合、qaの各メンバの値が初期化されずに計算に使われ、未定義動作になる可能性があります。
C++の場合(開示されていない)struct quantityのコンストラクタなどで初期化されている可能性が考えられるので、
未初期化の値が使われると断定することはできません。
C言語の場合、qaの各メンバの値が初期化されずに計算に使われ、未定義動作になる可能性があります。
C++の場合(開示されていない)struct quantityのコンストラクタなどで初期化されている可能性が考えられるので、
未初期化の値が使われると断定することはできません。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)