質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.33%

  • C++

    3770questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

C言語 行列の乗算 ポインタの扱い

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 732

ISARIA

score 18

大学の課題です。コードを書いていて止まってしまったので助けてください。

3行2列の行列が格納されている.csvファイルと、2行4列の行列が格納されている.csvファイルがあり、コマンドライン引数を使って読み込み行列の乗算を行い、.その結果をcsvファイルとしてあらかじめ作った別フォルダに格納しろというものでした。

行列サイズは既知であるとしてプログラムを作成して構わないという指摘があったので、行列計算の中身は長ったらしいものの問題なく作れたとは思っているのですが、読み込んだファイルの中身を使う方法がわからなくなっています。
また、別フォルダへの格納というものの方法を教えていただきたいと思います。
よろしくお願いいたします。

以下が現在の状態です。/*行列の計算*/の中身はforを使って書き直しています。

/*
    a_mat.csv には3行2列の行列 A を表すデータ列が格納されており、
    b_mat.csv には2行4列の行列 B を表すデータ列が格納されている。
    行列の乗算 A * B を行い、結果を output_mat.csv として出力するプログラムを作成せよ。
    また、output_mat.csv はex1のフォルダに新たにoutputというディレクトリをあらかじめ手動で作成しておき、
    そこのディレクトリ内に出力するプログラムを作成すること。
*/

#include<stdio.h>
#include<stdlib.h>

//計算処理を行う関数
void operation(FILE* ifp1, FILE*ifp2, FILE* ofp)
{
    //int mat_c[3][4] = ofp;        //答えの方
    const int mat_a_r = 3;        //aの行列の行数(横列)
    const int mat_a_c = 2;        //aの行列の列数(縦列)
    const int mat_b_r = 2;        //bの行列の行数(横列)
    const int mat_b_c = 4;        //bの行列の列数(縦列)
    float a;
    float b;

    if((ifp1==NULL)||(ifp2==NULL)||(ofp==NULL))        //ファイルポインタのエラー処理
    {
        fprintf(stderr,"[Error]null file pointer detecter.\n");
        exit(-1);
    }

    /*
    ifp1の内容をint型に書き換え
    */
    const int mat_a[3][2] = {*(ifp1),*(ifp1+1),
                            *(ifp1+2),*(ifp1+3),
                            *(ifp1+4),*(ifp1+5)};
    /*
    ifp2の内容をint型に書き換え
    */
    const int mat_b[2][4] = {*(ifp2),*(ifp2+1),*(ifp2+2),
                            *(ifp2+3),*(ifp2+4),*(ifp2+5)};

    /*
    行列の計算
    */
    fprintf(ofp,"mat_a[0][0]*mat_b[0][0]+mat_a[0][1]*mat_b[1][0], mat_a[0][0]*mat_b[0][1]+mat_a[0][1]*mat_b[1][1], mat_a[0][0]*mat_b[2][0]+mat_a[0][1]*mat_b[2][1], mat_a[0][0]*mat_b[3][0]+mat_a[0][1]*mat_b[3][1]\n");
    fprintf(ofp,"mat_a[1][0]*mat_b[0][0]+mat_a[1][1]*mat_b[1][0], mat_a[1][0]*mat_b[0][1]+mat_a[1][1]*mat_b[1][1], mat_a[1][0]*mat_b[2][0]+mat_a[1][1]*mat_b[2][1], mat_a[1][0]*mat_b[3][0]+mat_a[1][1]*mat_b[3][1]\n");
    fprintf(ofp,"mat_a[2][0]*mat_b[0][0]+mat_a[2][1]*mat_b[1][0], mat_a[2][0]*mat_b[0][1]+mat_a[2][1]*mat_b[1][1], mat_a[2][0]*mat_b[2][0]+mat_a[2][1]*mat_b[2][1], mat_a[2][0]*mat_b[3][0]+mat_a[2][1]*mat_b[3][1]\n");

}

int main(int argc, char* argv[])
{
    FILE* ifp1 = NULL;        //入力用ファイルポインタ
    FILE* ifp2 = NULL;        //入力用ファイルポインタ
    FILE* ofp = NULL;        //出力用ファイルポインタ
    char* ifile1 = NULL;    //入力ファイル名
    char* ifile2 = NULL;    //入力ファイル名
    char* ofile = NULL;        //出力ファイル名

    if(argc!=4)        //実行時引数が3個なかったらエラーとする
    {
        fprintf(stderr,"usage: %s inputfile outputfile\n", argv[0]);
        exit(1);
    }

    printf(" %s, %s を読み込みました\n", argv[1],argv[2]);
    printf(" %s に出力します。\n", argv[3]);

    ifile1 = argv[1];        //パラメータの1番目を入力ファイル名
    ifile2 = argv[2];        //パラメータの2番目を入力ファイル名
    ofile = argv[3];        //パラメータの2番目を入力ファイル名

    if((ifp1 = fopen(ifile1,"rt"))==NULL)        //入力ファイルを開く(rt:読み取り用に)
    {
        fprintf(stderr,"Can't open file %s\a\n", ifile1);        //開けなかったら終了
        exit(2);
    }

    if((ifp2 = fopen(ifile2,"rt"))==NULL)        //入力ファイルを開く(rt:読み取り用に)
    {
        fprintf(stderr,"Can't open file %s\a\n", ifile2);        //開けなかったら終了
        exit(2);
    }

    if((ofp = fopen(ofile,"wt"))==NULL)        //出力ファイルを開く(wt:書き込み用に)
    {
        fprintf(stderr,"Can't open file %s\a\n", ofile);        //開けなかったら終了
        exit(3);
    }

    operation(ifp1,ifp2,ofp);        //計算処理関数呼び出し

    fclose(ofp);        //ファイル名を閉じる
    fclose(ifp1);        //ファイル名を閉じる
    fclose(ifp2);        //ファイル名を閉じる

    return(0);
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

+6

えーと...なんかとてつもない勘違いしてませんか?

ファイルポインタFILE*はファイルのナカミを差してるわけじゃありませんよ?
freadとかfgetsとかfscanfとかを使って読み出さねばなりません。
そこんとこがばっさり抜け落ちてます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/12 10:28

    ありがとうございます!

    キャンセル

checkベストアンサー

+1

べた書きのCプログラムです

/*
    a_mat.csv には3行2列の行列 A を表すデータ列が格納されており、
    b_mat.csv には2行4列の行列 B を表すデータ列が格納されている。
    行列の乗算 A * B を行い、結果を output_mat.csv として出力するプログラムを作成せよ。
    また、output_mat.csv はex1のフォルダに新たにoutputというディレクトリをあらかじめ手動で作成しておき、
    そこのディレクトリ内に出力するプログラムを作成すること。
*/
#include<stdio.h>
#include<stdlib.h>

//計算処理を行う関数
void operation(FILE* ifp1, FILE*ifp2, FILE* ofp)
{
    int mat_a[3][2];        //matlix A
    int mat_b[2][4];        //matlix B
    int i;

    if((ifp1==NULL)||(ifp2==NULL)||(ofp==NULL))        //ファイルポインタのエラー処理
    {
        fprintf(stderr,"[Error]null file pointer detecter.\n");
        exit(-1);
    }
    /*
    ifp1の内容をint型に書き換え
    */
        for(i=0; i<3; i++) fscanf(ifp1,"%d,%d",&mat_a[i][0],&mat_a[i][1] );
    /*
    ifp2の内容をint型に書き換え
    */
        for(i=0; i<2; i++) fscanf(ifp2,"%d,%d,%d,%d",&mat_b[i][0],&mat_b[i][1],&mat_b[i][2],&mat_b[i][3] );

    /*
    行列の計算
    */
    fprintf(ofp,"%d,%d,%d,%d\n",mat_a[0][0]*mat_b[0][0]+mat_a[0][1]*mat_b[1][0],
                                mat_a[0][0]*mat_b[0][1]+mat_a[0][1]*mat_b[1][1],
                                mat_a[0][0]*mat_b[0][2]+mat_a[0][1]*mat_b[1][2],
                                mat_a[0][0]*mat_b[0][3]+mat_a[0][1]*mat_b[1][3]);
    fprintf(ofp,"%d,%d,%d,%d\n",mat_a[1][0]*mat_b[0][0]+mat_a[1][1]*mat_b[1][0],
                                mat_a[1][0]*mat_b[0][1]+mat_a[1][1]*mat_b[1][1],
                                mat_a[1][0]*mat_b[0][2]+mat_a[1][1]*mat_b[1][2],
                                mat_a[1][0]*mat_b[0][3]+mat_a[1][1]*mat_b[1][3]);
    fprintf(ofp,"%d,%d,%d,%d\n",mat_a[2][0]*mat_b[0][0]+mat_a[2][1]*mat_b[1][0],
                                mat_a[2][0]*mat_b[0][1]+mat_a[2][1]*mat_b[1][1],
                                mat_a[2][0]*mat_b[0][2]+mat_a[2][1]*mat_b[1][2],
                                mat_a[2][0]*mat_b[0][3]+mat_a[2][1]*mat_b[1][3]);
}

int main(int argc, char* argv[])
{
    FILE* ifp1   = NULL;    //入力用ファイルポインタ
    FILE* ifp2   = NULL;    //入力用ファイルポインタ
    FILE* ofp    = NULL;    //出力用ファイルポインタ
    char* ifile1 = NULL;    //入力ファイル名
    char* ifile2 = NULL;    //入力ファイル名
    char* ofile  = NULL;    //出力ファイル名

    if(argc!=4)        //実行時引数が3個なかったらエラーとする
    {
        fprintf(stderr,"usage: %s inputfile outputfile\n", argv[0]);
        exit(1);
    }

    printf(" %s, %s を読み込みました\n", argv[1],argv[2]);
    printf(" %s に出力します。\n", argv[3]);

    ifile1 = argv[1];      //パラメータの1番目を入力ファイル名
    ifile2 = argv[2];      //パラメータの2番目を入力ファイル名
    ofile  = argv[3];      //パラメータの2番目を入力ファイル名

    if((ifp1 = fopen(ifile1,"rt"))==NULL)        //入力ファイルを開く(rt:読み取り用に)
    {
        fprintf(stderr,"Can't open file %s\a\n", ifile1);        //開けなかったら終了
        exit(2);
    }

    if((ifp2 = fopen(ifile2,"rt"))==NULL)        //入力ファイルを開く(rt:読み取り用に)
    {
        fprintf(stderr,"Can't open file %s\a\n", ifile2);        //開けなかったら終了
        exit(2);
    }

    if((ofp = fopen(ofile,"wt"))==NULL)        //出力ファイルを開く(wt:書き込み用に)
    {
        fprintf(stderr,"Can't open file %s\a\n", ofile);        //開けなかったら終了
        exit(3);
    }

    operation(ifp1,ifp2,ofp);        //計算処理関数呼び出し

    fclose(ofp);        //ファイル名を閉じる
    fclose(ifp1);        //ファイル名を閉じる
    fclose(ifp2);        //ファイル名を閉じる

    return(0);
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/12 10:32

    ありがとうございました!

    キャンセル

+1

ファイルの読み込み処理には、fread/fgets/fscanfなどいくつかありますが、今回の場合ではフォーマットが決まっていて汎用的な処理は不要と思われるので、fscanfによる実装で良いと思います。
課題ということなのでコードまでは書きませんが、下記サイトなどを参考にしてみてください。
http://www.c-tipsref.com/reference/stdio/fscanf.html

別フォルダへの格納というものの方法を教えていただきたいと思います。 

これは既に起動時の第三パラメーターに出力先を指定するようになっているので、今のままで出来ていると思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/12 10:27

    ありがとうございます!

    キャンセル

+1

こんにちは。

テキスト・ファイルの読み込みと出力ができないで困っているようですね。
とりあえず、3x2行列のcsvファイルを読み込んで表示するサンプルです。

出力先をstd::ofstreamにすることでファイルへ出力できます。

#include <iostream>
#include <fstream>

int main(int argc, char* argv[])
{
    if (argc < 2)
return 1;

    double matrix0[3][2];

    std::ifstream ifs(argv[1]);
    for (int i=0; i < 3; ++i)
    {
        for (int j=0; j < 2; ++j)
        {
            if (j != 0)
            {
                ifs.ignore(256, ',');
            }
            ifs >> matrix0[i][j];
        }
    }

    for (int i=0; i < 3; ++i)
    {
        for (int j=0; j < 2; ++j)
        {
            std::cout << matrix0[i][j] << " ";
        }
        std::cout << "\n";
    }

    return 0;
}

csvファイル

1.1, 1.2
2.1, 2.2
3.1, 3.2

実行結果

1.1 1.2
2.1 2.2
3.1 3.2

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/12 10:34

    丁寧な説明をありがとうございました。m(_)m

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.33%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • C++

    3770questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。