59465

[code]

    入力される値
    2
    2 5
    3 4
    
    期待する出力
    hello = 2 , world = 5 
    hello = 3 , world = 4
    
[/code]

の場合のコードは、

[code]

    #include <stdio.h>
    int main(void){
      int i, n;
      char buf[1000];
      char token1[100], token2[100];
    
      fgets(buf, sizeof(buf), stdin);
      sscanf(buf, "%d\n", &n);
      for (i=0; i<n; i++) {
        fgets(buf, sizeof(buf), stdin);
        sscanf(buf, "%s %s\n", token1, token2);
        printf("hello = %s , world = %s\n" ,token1 ,token2);
      }
      return 0;
    }
    
[/code]

このように、決まったフォーマットのデータを読み込む際はsscanfとfgetsを組み合わせると、上手くいきますが、  
入力されるフォーマットが以下のように不規則の場合、sscanfとfgetsを組み合わせてファイルを読み込むことはできるのでしょうか？（全てint型）

[code]

    入力フォーマット   
    M N  
    c_1  
    c_2  
    ...  
    c_M
    a_{1,1} a_{1,2}  ... a_{1,M}  
    a_{2,1} a_{2,2}  ... a_{2,M}  
    ...  
    a_{N,1} a_{N,2}  ... a_{N,M}
    
    入力例１
    3 3
    250
    500
    1000
    100 200 300
    30 250 0
    1 1 1000
    
    入力例2
    5 1
    123
    456
    789
    111
    220
    10 10 10 10 10
    
[/code]


CC BY-SA 4.0
2019-10-04T07:40:42.580
59456
2019-10-05T08:57:56.237
34550
question
c
C言語でファイル読み込みの方法


一般的には、1行のデータを読み込んで、頭から1文字ずつチェックし、それが数字かスペースか、CR、LFかを判定し、それぞれに適切な処理を行っていくことになると思います。


CC BY-SA 4.0
2019-10-04T08:07:16.353
59459
2019-10-04T08:07:16.353
24490
59456
answer


その区切るフォーマットがきちんと定義されているならばどうとでもなります  
＃sscanf を使うかどうかは別の話として


CC BY-SA 4.0
2019-10-04T08:08:58.957
59460
2019-10-04T08:08:58.957
27481
59456
answer


横方向のときもscanfが使えます。

[code]

    #include<stdio.h>
    int a[10];
    int main()
    {
        int i, j, n;    
        scanf("%d", &n);
        for (i = 0; i < n; i++) scanf("%d", a+i);
        for (j = 0; j < i; j++) printf("%d\n", a[j]);
    }
    
[/code]

入力例は、

[code]

    3
    1 2 3
    
[/code]

です。3つ読めました。

sscanfを使うときは、

[code]

    int a[10];
    int main()
    {
        int i, n, len;
        char s[20], t[10], *p = s;
    
        fgets(t, 10, stdin);
        sscanf(t, "%d", &n);
    
        fgets(s, 20, stdin);
        for (i = 0; i < n; i++) {
            char s2[5];
            sscanf(p, "%s", s2);
            sscanf(s2, "%d", a+i);
            len = strlen(s2);
            p+=len+1; // スペース１こ
        }
        for (i = 0; i < n; i++) printf("%d\n", a[i]);
    }
    
[/code]

です。  
sscanfでは、ストリームではなく文字列から読み取るので、自分で読み取り位置を調整する必要があります。


CC BY-SA 4.0
2019-10-04T10:43:55.110
59465
2019-10-04T13:23:16.727
2019-10-04T13:23:16.727
35281
35281
59456
answer


rueさんが`sscanf`を使った回答をされていますが、もう少しきれいに書けます。[`scanf`系](https://ja.cppreference.com/w/c/io/fscanf)にはそれまでに読み込んだ文字数を返す`%n`があります。これを使うことで一旦`%s`で切り取り長さを調べる必要がなくなり、直接`%d`で数値を取得できます。
[wandbox](https://wandbox.org/permlink/nMXnk3hog0wVznRo)

[code]

    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
        char buffer[256], *p;
        int n, *data;
        fgets(buffer, 256, stdin);
        sscanf(buffer, "%d", &n);
        data = calloc(n, sizeof(int));
        fgets(buffer, 256, stdin);
        p = buffer;
        for (int i = 0; i < n; i++) {
            int read;
            sscanf(p, "%d%n", data + i, &read);
            p += read;
        }
        for (int i = 0; i < n; i++)
            printf("%d\n", data[i]);
        free(data);
        return 0;
    }
    
[/code]


CC BY-SA 4.0
2019-10-05T08:57:56.237
59479
2019-10-05T08:57:56.237
4236
59456
answer