プログラミング(C言語)の質問です。
コマンドライン引数を使って3点の座標の並びが1レコードに記録されたファイルを読み込み、3点の並びが、時計回りに三角形を形作るか、反時計回りに三角形を形作るか、直線(あるいは一点)上にあるかを判定し、読み込んだ各レコードを判定に従って、3つの出力ファイル(時計回りだけのファイル、反時計回りだけのファイル、直線だけのファイル)に分配して書き込むプログラムを作成しています。しかし、なかなか完成しない上、どこが間違っているのかも分かりません。下に私が作ったプログラムを添付しておくのでどこが間違っているのか指摘してください。よろしくお願いします。
#include <stdio.h>
#define BUFLEN 1024
int main(int argc, char *argv[]){
int difference_x1, difference_y1, difference_x2, difference_y2;
int cross_product;
char buf[BUFLEN];
struct points{
int x;
int y;
} point_a, point_b, point_c;
FILE *fp1, *fp2;
while(fgets(buf, BUFLEN, fp1) != NULL){
fp1 = fopen(argv[1], "r");
fgets(buf, BUFLEN, fp1);
sscanf(buf, "%d,%d,%d,%d,%d,%d", &point_a.x, &point_a.y, &point_b.x, &point_b.y, &point_c.x, &point_c.y);
difference_x1 = point_b.x - point_a.x;
difference_y1 = point_b.y - point_a.y;
difference_x2 = point_c.x - point_a.x;
difference_y2 = point_c.y - point_a.y;
cross_product = difference_x1 * difference_y2 - difference_x2 * difference_y1;
if(cross_product < 0){
fp2 = fopen("clockwise.txt", "w");
}else if(cross_product > 0){
fp2 = fopen("counterclockwise.txt", "w");
}else if(cross_product == 0){
fp2 = fopen("straightline.txt", "w");
}
fprintf(fp2, "%d,%d,%d,%d,%d,%d", point_a.x, point_a.y, point_b.x, point_b.y, point_c.x, point_c.y);
fclose(fp2);
}
fclose(fp1);
return 0;
}
A 回答 (5件)
- 最新から表示
- 回答順に表示
No.5
- 回答日時:
>どこが間違っているのか指摘してください。
1)
>while(fgets(buf, BUFLEN, fp1) != NULL){
↑コンパイル時に「警告」がでますよね、fp1 は値が代入される前に使われたと。
これを無視せず、
>fp1 = fopen(argv[1], "r"); を前にし、fp1 を確定しましょう。
2)
>fp2 = fopen("clockwise.txt", "w");
これらファイルオープン3行は「新規」ですので、「書き込み」の条件合致の都度、新たにオープンします。
(= >最後に判定したものしか書き込まれていません)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
以上、大きく2点について修正したものでアドバイス(BorlandC++5.5.1)。
あと、
・fgets() + sscanf() を fscanf() で代用しています。
・出力3ファイルのファイルポインタを使っています。
http://www.bohyoh.com/CandCPP/C/Library/fscanf.h …
《蛇足》
プログラムの作成・実行は、自己責任?の世界です。
不具合時に、困るのは自分です。
例)実行時、コマンドラインに、入力ファイル名を付け忘れた場合。
これへの対応をコード化しておくも、しないも自由です。
ただし、
☆課題等でソースを提出する場合は、上への対応や「ファイルがオープンできない」場合等の「エラー処理」を記述しておくことが必須となります。
#include <stdio.h>
#define TOKEI 0
#define HNTKI 1
#define SLINE 2
int main( int argc, char *argv[] )
{
int difference_x1, difference_y1, difference_x2, difference_y2;
int cross_product;
FILE *fp1, *fp2, *fP[ 3 ];
struct points{
int x;
int y;
}point_a, point_b, point_c;
fp1 = fopen( argv[ 1 ], "r" );
fP[ TOKEI ] = fopen( "clockwise.txt", "w" );
fP[ HNTKI ] = fopen( "counterclockwise.txt", "w" );
fP[ SLINE ] = fopen( "straightline.txt", "w" );
while( 6 == fscanf( fp1, "%d,%d,%d,%d,%d,%d", &point_a.x, &point_a.y, &point_b.x, &point_b.y, &point_c.x, &point_c.y ) ){
difference_x1 = point_b.x - point_a.x;
difference_y1 = point_b.y - point_a.y;
difference_x2 = point_c.x - point_a.x;
difference_y2 = point_c.y - point_a.y;
cross_product = difference_x1 * difference_y2 - difference_x2 * difference_y1;
fp2 = fP[ SLINE ];
if( cross_product < 0 ) fp2 = fP[ TOKEI ];
if( cross_product > 0 ) fp2 = fP[ HNTKI ];
fprintf( fp2, "%d,%d,%d,%d,%d,%d\n", point_a.x, point_a.y, point_b.x, point_b.y, point_c.x, point_c.y );
}
fcloseall();
return( 0 );
}
注:インデントに全角空白を用いています。コピペ後、タブに一括変換して下さい。
No.4
- 回答日時:
まあ、あれでしょうか。
fp2を3種類のファイルで使い回す代わりに、
1ファイルについて1ファイルポインターを対応させるのが、
わかりやすくてよいかもしれません。
No.3
- 回答日時:
>3つのファイルができたのはいいんですが、最後に判定したものしか書き込まれていません。
だとすると、
>指摘された通り直したら上手くいきました。
そうではなくて、まだうまくいきません、ですね。
書込み用ファイルのオープンモードはどうなっていますか?
No.2
- 回答日時:
>while(fgets(buf, BUFLEN, fp1) != NULL){
この「前に」ファイルをオープンしてください。
>fp1 = fopen(argv[1], "r");
この文は、ループの外に出してください。そして、
この文の前で、コマンドライン引数の個数をチェックしてください。
また、オープンがうまくいかなかったときの処理を加えてください。
>fgets(buf, BUFLEN, fp1);
この文は不要です。
>fp2 = fopen("clockwise.txt", "w");
毎回、新規作成モード("w")でよいのでしょうか?
また、オープンがうまくいかなかったときの処理を加えてください。
>}else if(cross_product == 0){
負でも正でもなければゼロに決まっていますので、
if~ は冗長です。else { でじゅうぶんです。
まだ、他にあるかもしれません。
この回答への補足
回答ありがとうございます。
指摘された通り直したら上手くいきました。
ただ、3つのファイルができたのはいいんですが、最後に判定したものしか書き込まれていません。判定したもの全てが書き込まれているようにしたいのですがどうしたらよいでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# 未解決の外部シンボル _printfが関数_mainで参照されました 1 2022/09/18 15:28
- Java java 引数 戻り値のあるメソッド 3 2023/02/12 06:23
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- Excel(エクセル) RANK.EQとCOUNTIFSの組み合わせで同ポイントの場合、違う条件を加えて順位を付けたい。 1 2022/08/30 19:49
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- 英語 "by a ~ 0.5 percentage point"が単数となる理由等について 2 2023/05/11 10:41
- FX・外国為替取引 mql4のコンパイルエラー箇所の修正お願いします。 1 2023/03/15 16:14
- スーパー・コンビニ イオンカードで、レジでWAON POINTを使って支払いたい時、電子マネーWAONカードのように機械 1 2023/03/12 05:44
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
なぜCSQとCIP形式ではコ...
-
複数ファイルの同時読み込みの...
-
ファイルが読み込めない・・・
-
c言語 ファイルから数字を読み...
-
日本語ファイル名のFTPについて
-
C言語を用いて、csvファイル内...
-
fgets( ) の返り値は何?
-
ガンマ変換 C言語でプログラ...
-
C言語でのCSVソートとデータ抽...
-
C言語でファイル読み書きを早く...
-
構造体とファイル検索(><)
-
音声データを出力するCプログラ...
-
lockfについて
-
画像を読み込み、画素値の度数...
-
ファイルへの書込み処理が異常...
-
乱数とファイルの入出力の質問...
-
csvfファイルの1行目と3行目を...
-
テキストファイル内に対して, ...
-
C言語におけるファイル読み込み...
-
#define _CRT_SECURE_NO_WARNIN...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
c言語でのfscanfについて
-
C言語でファイル読み書きを早く...
-
fopenでファイル名に、変数を使...
-
複数ファイルの同時読み込みの...
-
fgets( ) の返り値は何?
-
テキストファイル内に対して, ...
-
ファイルへの書込み処理が異常...
-
C言語にてXMLファイルから任意...
-
ファイル出力で改行を入れたい!
-
C言語でセグメンテーションエ...
-
エラーがわかりません、、
-
ガンマ変換 C言語でプログラ...
-
自己相関関数を求めるプログラ...
-
VisualStudioでのファイルの入...
-
同時にファイル読み込み 書き込み
-
c言語 ファイルから数字を読み...
-
大量の入力ファイルを扱うとき...
-
ファイルが読み込めない・・・
-
【C言語】ファイルを読み込んで...
-
a*(1-exp(-bx))+cの近似の方法
おすすめ情報