(※ 現在修正中です…)
[指摘]
関係ない部分ですが気になった部分を書きます。
まず一つ目。変数名 等はちゃんと名前を付けるべきです。
趣味で自分ひとりで開発する場合でも保守は当たり前のようにやります。一か月前のコードに手を入れるとか当たり前のことです。一か月前の自分はもはや他人です。自分が組んだコードですらマジで忘れています。読めばわかるとは思いますが、変数名がでたらめだとわかりにくくなります。ましてや実際に会社とかで開発する際は複数人で開発するのが当たり前のようなので、わかるわけないです。ちゃんと変数名を定義しましょう。
inputalley[alleysize];
→ inputarray[arraysize]では?
二つ目。記号の意味を明確に理解すべきです。
if(mode = 0)
となっていますが、C言語やC++においてはif文内の条件式で 「=演算子」は「単なる代入」です。つまり、「modeの値が0なら」ではなく「modeに0を代入できるなら」的な意味になってしまいます。
そうなるとtrueになるのでelseとかに行きません。
三つ目。関数をちゃんと理解しましょう。引数や戻り値の理解がまったく出来ていません。
input関数を見ると、int input(int alleysize ,int* write)
となっていますが、それぞれの引数・戻り値はどういう意味でしょうか? 引数 alleysizeの役割は? 引数 writeの役割は? input関数の戻り値であるintの役割は?
input関数の定義を見ると、
C
1int input (int alleysize ,int* write)
2{
3 int num;
4 char inputalley[alleysize];
5 fgets(inputalley,alleysize,stdin);
6 num = atoi(inputalley);
7 *write = num;
8 return 0;
9}
となっていますが、ちょっと違和感があります。
まず、なぜ第一引数alleysizeが必要なのでしょうか? 処理内容を考えると別に必要ないのでは?
コードを読んでみましょう。
コードを読むコツは「一行レベルで、その行が何をしているかを考えながら読む」です。
C
1int input (int alleysize ,int* write)
2{
3
4 int num;
5 char inputalley[alleysize];
6 fgets(inputalley,alleysize,stdin);
7 num = atoi(inputalley);
8 *write = num;
9 return 0;
10}
を読むと、
C
1int input (int alleysize ,int* write)
2{
3 // 変数numを宣言する
4 int num;
5 // 要素数alleysizeとした配列inputalleyを宣言する
6 char inputalley[alleysize];
7 // 標準入力からalleysize分inputalleyに入れる
8 fgets(inputalley,alleysize,stdin);
9 // inputalleyの文字列データを整数に変換してnumに入れる
10 num = atoi(inputalley);
11 // 戻り値扱いの第二引数writeにnumを設定
12 *write = num;
13 // 戻り値として0を返す
14 return 0;
15}
となる。
で、char型配列inputalleyを宣言していますが、要素数を考えてみてください。
たとえばinput( 2, &n );
と呼び出したなら、inputalley[2];
となるはずです。
char型配列の場合で文字列と見なすなら「終端文字」('\0'とか)が末尾につきます。
"Hello World"であれば "Hello World\0" という風に終端文字が付きますから、実際には本来の文字数 + 1 が必要になります。引数alleysizeが 2 であれば 実際の文字数は 2 - 1 = 1 つまり1文字分だけです。
(厳密には文字数ではなくバイト数ですが。)
よって
C
1// main関数内
2
3 printf("何を示しますか。\n0 : 税込み価格\nそれ以外 : 割引価格\n");
4
5 input(1,&mode);
を読むと、要素数1 (実際に入れることができる文字数は1 - 1 = 0なので 0文字)なのでスキップされたような状態に。
さらに戻り値として return 0;
と返していますがこれは意味あるのでしょうか?
仮にprintf関数とかみたいに他人が使うとしたら勘違いされますよ。
戻り値を返しているはずなのに意味のない値を返している。これならいっそvoidとして「戻り値無し」とした方がいいです。混乱のもとです。
「関数」「引数」「戻り値」これらが分かっていればありえないバグです。(厳密にはバグの温床になりやすいですが)
そして四つ目。おそらくここが原因だと考えています。「標準入出力を使う場合、バッファを意識せよ」です。
軽いサンプルとして、
C
1#include <stdio.h>
2#include<stdlib.h>
3int input (int alleysize ,int* write)
4{
5 int num;
6 char inputalley[alleysize];
7 fgets(inputalley,alleysize,stdin);
8 num = atoi(inputalley);
9 *write = num;
10 return 0;
11}
12
13int main( void )
14{
15 int n;
16 input( 3, &n );
17 printf( "n = %d\n", n );
18 int m;
19 input( 3, &m );
20 printf( "m = %d\n", m );
21 int p;
22 input( 3, &p );
23 printf( "p = %d\n", p );
24return 0;
25}
とやってみたところ、nとpは入力を促されるが、mだけはなぜかスキップされる。(nを入力直後に"n = ..."と"m = ..."が同時に表示される)
C++でも一応この問題があって、cin >> 変数;
の直後にstd::getline( ... );
を使うとスキップされるという現象があります。
ユーザがコンソールに入力する。するとコンソールに文字列なり数値なりのデータが記録され、そこからNバイト分読み取っているようです。たとえば10バイト分入力したとしてfgets関数とかで4バイト分取り出した場合、コンソールには 10 - 4 = 6バイト分データがまだ残っています。
この残ったデータがあるので二回目のfgets関数が取り出すときに残りのデータを『新しく入力されたもの』と解釈して読み取る。そうするとユーザは入力していないのになぜか「入力された」と解釈していますからスキップされたような状態になります。
恐らくこれが原因かと。
「C言語 標準入力 スキップされる」で検索すると質問: ch = getchar();が時折スキップされます。がヒットします。
使っている関数がgetchar関数ですが発想は同じです。上記のある回答者の方の仰るようにfflush関数を使ってコンソール内のデータをフラッシュすると上手くいくのではないかと。