2017-11-23 21 views
1

私の宿題には問題があります。 stdinでは、私は具体的にフォーマットされた入力を得るでしょう。特定の形式(行列)で入力してください

最初の行には、行列(行と列)のサイズを決定する2つの整数があります。後のすべての行は、行列の行を表します。

私は本質的にgetline()のようなことをしたいのですが、getline()を使いたくありません。実際、私は宿題で禁じられていません。したがって、私はint(または、私が推測するcharのchar)でintをスキャンする必要があります。ここでの問題は、防弾にする必要があることです(ほとんど)。少なくともダミープルーフ。

私は、EOFとその中に常にある行を読み、別のループ(おそらく?)の中で、自分の割り当てられた行列に保存して、次の行に移るループを想像しています。私は '\ n'をチェックすることになっているはずですが、今日は解決策を考える能力がないと思います。

ここで私が働いているのは:私の行列は構造体です。

struct Matrix{ 
    int nrows; 
    int ncols; 
    int** matrix; 
}; 

次に、複数の機能があります。

動的に特定のサイズの行列のためのスペースを割り当てる機能:

struct Matrix init_matrix(int r, int c) 
{ 
    struct Matrix mat; 
    mat.nrows = r; 
    mat.ncols = c; 
    mat.matrix = calloc(r, sizeof(int *)); 
    for(int i = 0; i < r; ++i) 
    { 
     *(mat.matrix+i) = calloc(c, sizeof(int)); 
    } 

    return mat; 
} 

機能以前に割り当てられたスペース解放する:

void free_matrix(struct Matrix mat) 
{ 
    int top = mat.nrows; 
    for(int i = 0; i < top; ++i) 
    { 
     free(mat.matrix[i]); 
    } 
    free(mat.matrix); 
} 

をこれら2つの機能は完全に正常に動作します。

今私は例えば、私が受け取ることになってるの入力を読み込みます関数create_matrix(ボイド)(少なくとも私はそれが任意の引数を取るべきではないと思います)、作成しようとしている:

3 3 
1 2 3 
4 5 6 
7 8 9 

関数が入力を読み込むと、入力が間違っているか、間違った形式であるかどうかを知ることができ、対応する終了値(100 feなど)でプログラムを終了できます。入力が正しい形式であれば、init_matrix )、入力を行列に保存します。あなたのより深い理解のために

:私が受け取ることになってる入力全体は以下のとおりです。 行列A(上記のように、最初の行のサイズ、後の行の値) 操作(+、 - 、*) 行列B

次に、操作(A * B、A + Bなど)を実行します。私はほとんどのものを関数にしようとしているので、メインは非常に簡単です。

int main(int argc, char *argv[]) 
{ 
    struct Matrix mat1 = create_matrix(); 
    char operation = get_operation(); 
    struct Matrix mat2 = create_matrix(); 
    struct Matrix result = compute(mat1,mat2, operation); 
    return 0; 
} 

あなたが私を手に入れたら何かがあります。私は、プログラムを複雑にして後で編集して、より大きなシーケンス(最大100個)の行列を2つしか扱えないようにしたいと思っています。今私はそれを汚れた方法で行うことができ、1つの操作で2つのマトリックスで動作させることができますが、それは私が本当に望むものではありません。

+1

質問は何ですか?あなたの計画はこれまでのところよく見えます。 –

+0

create_matrix関数の構造体です。最初にサイズの値をスキャンし、最初の行にあることを確認した後、残りの部分を行うより大きなスキャンを実行する方法を想像できません。私は2つのスキャンがあるだろうと思うのですが、私が想像することのできるものはすべてです。 – Welsy

+0

'getlines()'を使用できない場合、 'fgets()'を使って行を読み込みます。どちらも使用できない場合は、 'getline()'の代理人を作成してください。それは難しくありません。 'scanf()'関数は、改行を含む空白をスキップし、データが正しい行にあることを保証するために単純に使用することはできません。処理する行があれば、 'sscanf()'をループで使用してください。 –

答えて

1

これは私が解決した方法です。できます。それは完璧に近いところではないが、それは動作し、アップロードシステムはそれを取ってポイントをフルに与えたので、私は満足している。

struct Matrix read_matrix(FILE *fp) 
{ 
    struct Matrix mat; 
    //FIRST LINE 
    int ch; 
    int i = 0; 
    int n = 20; 
    char* line = calloc(n,sizeof(char)); 
    while((ch = fgetc(fp)) != EOF && ch != '\n') 
    { 
     *(line + i++) = ch; 
    } 
    *(line + n-1) = '\0'; 
    int r,c; 
    int k = sscanf(line,"%d %d", &r, &c); 
    if(k != 2) 
    { 
     fprintf(stderr, "Error: Chybny vstup!\n"); 
     exit(100); 
    } 
    free(line); 
    //MATRIX 
    line = calloc(c, sizeof(int)); 
    mat = init_matrix(r, c); 
    i = 0; 
    r = 0; 
    while(r < mat.nrows && (ch = fgetc(fp))) 
    { 
     if(ch == '\n' || ch == EOF) 
     { 
      *(line + i) = '\0'; 
      int offset; 
      char *data = line; 
      for(int j = 0; j < mat.ncols; ++j) 
      { 
       int d = sscanf(data, " %d%n", &mat.matrix[r][j], &offset); 
       if(d != 1){ 
        fprintf(stderr, "Error: Chybny vstup!\n"); 
        exit(100); 
       } 
       data += offset; 
      } 
      i = 0; 
      ++r; 
      if(ch == EOF){ 
       break; 
      } 
     } else 
     { 
      *(line + i++) = ch; 
     } 
    } 
    free(line); 
    return mat; 
}