`data.txt`からその数字を読み込み、その読み込んだ数字は出力できたのですが、最大値と最小値を出力するプログラムを作成する方法がわかりません。  
ちなみに、`data.txt`には

```

    23   12   17   67   45   59   12   96   33   87
    
```

という数字を打ち込んだため、以下のようなプログラムを実装すると、実行結果には

```

    $ ./a.out
       23   12   17   67   45   59   12   96   33   87
    
```

とでてきます。

```

    #include <stdio.h>
    
    const int N=10;
    
    int main()
    { 
        FILE *fp;
        int i,data[N];
        char fname[]="data.txt";
        if ((fp=fopen(fname,"r"))==NULL){
            printf("それを開けることはできません。\n");
    
            return -1;
        }
        i=0;
        while(i<N){
            fscanf(fp,"%d",&data[i]);
            printf("%5d",data[i]);
            i++;
        }
        printf("\n");
        fclose(fp);
    }
    
```

最大値と最小値を出力させるためには、どこにどのような文を付け加えればいいのでしょうか。  
最小値や最大値を求めるためのプログラム自体は書くことができますが、それをどのように上記のプログラムに書き加え、条件を満たすプログラムを作成すればいいのかということがわかりません。

最小値、最大値を求めるプログラムを以下に示します。

**最小値を求めるプログラム**

```

    #include <stdio.h>
    
    void readIntArray(int a[], int size)
    {
        int i;
        for(i=0;i<size;i=i+1) {
            printf("%d番目?", i+1);
            scanf("%d",&a[i]);
        }
    }
    
    /* size個 のデータが入っている配列を 配列の先頭から順に出力する */
    void printIntArray(int a[], int size)
    {
         int i;
        for(i=0;i<size;i=i+1) {
            printf("%d ",a[i]);
        }
        printf("\n");
    }
    
    //要素数size の整数配列 a の中の最小値を返す．
    int minIntArray(int a[], int size)
    {
        int i,min;
        min=a[0];
        for(i=1;i<size;i=i+1) {
            if (a[i]<min) {
                min=a[i];
            }
        }
        return min;
    }
    
    int main(void)
    {
      int data[100], size, minv;
    
    
        printf("データの個数を入力してください：");
        scanf("%d",&size);
            
        readIntArray(data, size);
        printf("順番に出力:");
        printIntArray(data, size);
    
        minv = minIntArray(data, size); 
        
        printf("最小値は %d です．\n", minv);
    
        return 0;
    }
    
```

**最大値を求めるプログラム**

```

    #include <stdio.h>
    
    void readIntArray(int a[], int size)
    {
        int i;
        for(i=0;i<size;i=i+1) {
            printf("%d番目?", i+1);
            scanf("%d",&a[i]);
        }
    }
    
    /* size個 のデータが入っている配列を 配列の先頭から順に出力する */
    void printIntArray(int a[], int size)
    {
         int i;
        for(i=0;i<size;i=i+1) {
            printf("%d ",a[i]);
        }
        printf("\n");
    }
    
    int maxIntArray(int a[], int size)
    {
        int i,max;
        max=a[0];
        for(i=1;i<size;i=i+1) {
            if (a[i]>max) {
                max=a[i];
            }
        }
        return max;
    }
    
    int main(void)
    {
      int data[100], size, maxv;
    
        printf("データの個数を入力してください：");
        scanf("%d",&size);
            
        readIntArray(data, size);
        printf("順番に出力:");
        printIntArray(data, size);
    
        maxv = maxIntArray(data, size); 
        
        printf("最大値は %d です．\n", maxv);
    
        return 0;
    }
    
```
CC BY-SA 4.0
2020-10-03T05:38:37.700
70892
2020-10-07T10:37:39.227
2020-10-04T06:18:07.097
3060
41837
question
c
ファイルに保存された数字を読み込み、最大値と最小値を出力するプログラムを作成する方法がわからない
他の質問も見ました。そこでも似たようなことを指摘されていましたが、

  1. 各処理がどのような順番で実行されていくか、
  2. ある処理でどの変数が使用されるか、
  3. ある処理の後、変数がどのような状態になっているか

を意識すると良いと思います。

* * *

C言語などの手続き型言語の場合、処理の順番が重要になります。  
C言語の場合、main関数がプログラム本体になります。提示コードの場合、

### Step 1

```

    int main()
    {
        FILE *fp;
        int i, data[N];
        char fname[] = "data.txt";
        // この時点
    
```

この時点では fp, i, data[0] ~ data[N-1] にはめちゃくちゃな数値が入っており、  
fname には data.txt が入っています。

### Step 2

```

    if ((fp=fopen(fname,"r"))==NULL){
    
```

は内側から実行されていきます。

  1. まず `fopen(fname, "r")` でファイルを開きます。`fname` には "data.txt" が入っているので data.txt を開いて、そのファイルを示す何らかの値（=ファイルポインタ）を取得します。
  2. そして `fp=fopen( ... )` でその値を `fp` にセットします。
  3. `(fp= ... )==NULL` でその値が `NULL` であるか（失敗しているか）を確認します。
  4. `if ( ... ) ` で、もしもファイルオープンが失敗しているならば `{ }` の中に入り、失敗していなければ `{ }` の直後まで飛びます。

ファイルオープンが失敗しなかった場合を考えます。

### Step 3

```

        if ((fp=fopen(fname,"r"))==NULL){
            // ここはスキップされた
        }
        // ここ
    }
    
```

ここでは `fp` にはファイルポインタ, `fname` には "data.txt" が入っており、  
`i`, `data[0]` ~ `data[9]` にはめちゃくちゃな数値が入っています。

### Step 4

```

        if ((fp=fopen(fname,"r"))==NULL){
            // スキップ
        }
        i = 0;
        // ここ
    }
    
```

ここでは `fp` にはファイルポインタ、 `i` には 0、 `fname` には "data.txt" が入っており、`data[0]` ~
`data[9]` にはめちゃくちゃな数値が入っています。

### Step 5

```

        while(i<N){
    
```

で i < N である間 `{ }` の中を実行します。  
最初の実行では i=0 なので

```

            fscanf(fp,"%d", &data[i]);
            printf("%5d", data[i]);
            i++;
    
```

では

  1. `fp` の示すファイルから数字を読み取り `data[0]` に格納します。
  2. `data[0]` を表示し、
  3. i を+1します。

そして次の実行では `i` は 1 なので `data[1]` に格納します。

### Step 6

while文は `i` が 9 の時 の処理をした直後に `i < N` を満たさなくなり、

```

        i=0;
        while(i<N){
            fscanf(fp,"%d",&data[i]);
            printf("%5d",data[i]);
            i++;
        }
        // ここ
        printf("\n");
        fclose(fp);
    }
    
```

ここに飛びます。  
現時点で `fp` にはファイルポインタ、`i` には10、`data[0]` ~ `data[9]` にはファイルから読み取った数値、`fname` には
"data.txt" が入っています。

### Step 7

そして `printf("\n");` で改行を出力し `fclose(fp);` でファイルを閉じます。  
これで main関数が終わったのでプログラムは終了します。

* * *

さて、`minIntArray` では最小値値候補の配列とその数を引数として渡す必要があるようです。  
ここまでで `// ここ` と書いた中で、配列にめちゃくちゃな数字ではない、ファイルから読み取った数字が格納されている時点があるはずです。  
そこに `minIntArray(配列変数, 数)` と挿入すれば最小値が求まり、`最小値変数 = minIntArray(配列変数, 数)` とすれば
`最小値変数` に最小値が格納されます。（`最小値変数` は別途関数上部で宣言する必要があります。）

* * *

**上で「ここではこの変数の値が～で」と説明したのをデバッガを使うとその場で見ることが出来ます。**  
授業でgccか何かを使っているのだと思いますが、CLIでの操作に慣れないのでしたら個人的にIDEを導入することをお勧めします。
CC BY-SA 4.0
2020-10-07T10:37:39.227
70990
2020-10-07T10:37:39.227
20885
70892
answer