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

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

新規登録して質問してみよう
ただいま回答率
85.50%
C++

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

Q&A

解決済

2回答

23286閲覧

c++のDebug Assertion Failedについて

namekuhito

総合スコア21

C++

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

0グッド

0クリップ

投稿2019/05/04 05:28

編集2019/05/04 07:28

前提・実現したいこと

ファイルから座標を読み込んで、凸包を作りたいです。

発生している問題・エラーメッセージ

Expression:stream!=nullptr For information on how your program can cause an assertion failure,see the Visual C++ documentation on asserts

該当のソースコード

c++

1 2#define MAX_NUMBER 1000 3#define FLAG_OFF 0 4#define FLAG_ON 1 5#define EPS 0.000001 6#define V_NO_ERROR 0 7#define V_ERROR 1 8 9typedef struct { 10 double x, y; 11 int flag; 12}POINT; 13 14POINT p[MAX_NUMBER]; 15int number_of_points; 16 17int find_point_with_minimum_x(void); 18 19void make_2d_convex_hull(void); 20void take_coordinate_of_point(int point_number, double v[]); 21void determine_direction_of_base_line(double uv[], int point1, int point2); 22void sort_using_distance(int ct[], int n, int p); 23void vsub_(double v[], double v1[], double v2[], int *n); 24void vunit_(double v[], double v0[], int *n, int *ierror); 25double vinpro_(double v1[], double v2[], int *n); 26 27int main(void) 28{ 29 FILE *fp; 30 int i = 0; 31 int point_number; 32 int n = 2; 33 double v1[2], v2[2], v[2]; 34 double d; 35 errno_t err; 36 37 /*点データの入力*/ 38 if ((err = fopen_s(&fp,"point_table.dat.txt", "r")) == '0') { 39 printf("cannot open point_table.dat\n"); 40 return 0; 41 } 42 while (fscanf_s(fp, "%lf%lf", &p[i].x, &p[i].y) != EOF) { 43 p[i].flag = FLAG_OFF; 44 i++; 45 } 46 fclose(fp); 47 /*点の数の設定*/ 48 number_of_points = i; 49 50 /*点データの出力*/ 51 for (i = 0; i < number_of_points; i++) { 52 printf("%3d %7.3lf %7.3lf %d\n", i, p[i].x, p[i].y, p[i].flag); 53 } 54 /*2次元コンベックスハルの生成*/ 55 make_2d_convex_hull(); 56 57 return 0; 58} 59 60void make_2d_convex_hull(void) 61{ 62 int start_point; 63 int convex_point; 64 int number_of_convex_points = 0; 65 int cp[MAX_NUMBER];/*凸多角形を構成する点の並び*/ 66 int ctemp[10]; 67 int count; 68 int n = 2; 69 int ierror; 70 int i, k; 71 double v0[2], v1[2], v2[2], v[2], uv[2]; 72 double d, dmax; 73 74 /*座標が最小の点を求める*/ 75 convex_point = find_point_with_minimum_x(); 76 printf("凸多角形を構成する1番目の点:%d\n", convex_point); 77 start_point = convex_point; 78 cp[number_of_convex_points] = convex_point; 79 number_of_convex_points++; 80 81 /*基準線の方向を設定する(y軸の負の方向)*/ 82 uv[0] = 0.0; uv[1] = -1.0; 83 /*凸多角形を構成する2番目以降の点を求める*/ 84 while (1) { 85 take_coordinate_of_point(convex_point, v1); 86 k = convex_point; 87 dmax = -1.0; 88 for (i = 0; i < number_of_points; i++) { 89 if (i != convex_point || p[i].flag == FLAG_OFF) { 90 take_coordinate_of_point(i, v2); 91 vsub_(v0, v2, v1, &n); 92 vunit_(v, v0, &n, &ierror); 93 d = vinpro_(uv, v, &n); 94 if (fabs(dmax - d) < EPS) { 95 ctemp[count] = i; 96 count++; 97 } 98 else if (dmax < d) { 99 dmax = d; 100 k = i; 101 ctemp[0] = i; 102 count = 1; 103 } 104 } 105 } 106 if (count >= 2) { 107 /*距離を用いて点を並び替える*/ 108 sort_using_distance(ctemp, count, convex_point); 109 for (i = 0; i < count; i++) { 110 convex_point = ctemp[i]; 111 p[convex_point].flag = FLAG_ON; 112 cp[number_of_convex_points] = convex_point; 113 number_of_convex_points++; 114 printf("凸多角形を構成する%d番目の点:%d\n", number_of_convex_points, convex_point); 115 } 116 } 117 else { 118 convex_point = k; 119 p[convex_point].flag = FLAG_ON; 120 cp[number_of_convex_points] = convex_point; 121 number_of_convex_points++; 122 printf("凸多角形を構成する%d番目の点:%d\n", number_of_convex_points, convex_point); 123 } 124 /*最初の点の戻れば終了*/ 125 if (convex_point == start_point)break; 126 /*基準線の方向を設定する*/ 127 determine_direction_of_base_line(uv, cp[number_of_convex_points - 2], convex_point); 128 } 129} 130 131void take_coordinate_of_point(int point_number, double v[]) 132{ 133 v[0] = p[point_number].x; 134 v[1] = p[point_number].y; 135 136} 137 138int find_point_with_minimum_x(void) 139{ 140 int point_number; 141 int i; 142 double min; 143 144 point_number = 0; 145 min = p[0].x; 146 for (i = 1; i < number_of_points; i++) { 147 if (min > p[i].x) { 148 min = p[i].x; 149 point_number = i; 150 } 151 } 152 return point_number; 153} 154 155void determine_direction_of_base_line(double uv[], int point1, int point2) 156{ 157 double v1[2], v2[2], v[2]; 158 int n = 2; 159 int error; 160 161 take_coordinate_of_point(point1, v1); 162 take_coordinate_of_point(point2, v2); 163 vsub_(v, v2, v1, &n); 164 vunit_(uv, v, &n, &error); 165} 166void sort_using_distance(int ct[], int n ,int p) 167{ 168 int i, j, k; 169 double v1[2], v2[2]; 170 double dist[10]; 171 double d; 172 double min, temp1; 173 int temp2; 174 175 /*2点間の距離の計算*/ 176 take_coordinate_of_point(p, v1); 177 for (i = 0; i < n; i++) { 178 take_coordinate_of_point(ct[i], v2); 179 d = 0.0; 180 for (j = 0; j < 2; j++) { 181 d += (v2[j] - v1[j])*(v2[j] - v1[j]); 182 } 183 dist[i] = sqrt(d); 184 } 185 /*距離の昇順に点を並び替える*/ 186 for (i = 0; i < n - 1; i++) { 187 min = dist[i]; 188 k = i; 189 for (j = i + 1; j < n; j++) { 190 if (dist[j] < min) { 191 min = dist[j]; 192 k = j; 193 } 194 } 195 temp1 = dist[i]; 196 dist[i] = dist[k]; 197 dist[k] = temp1; 198 temp2 = ct[i]; 199 ct[i] = ct[k]; 200 ct[k] = temp2; 201 } 202} 203 204/*単位ベクトル*/ 205void vunit_(double v[], double v0[], int *n, int *ierror) 206{ 207 int i; 208 double d = 0.0; 209 *ierror = V_NO_ERROR; 210 for (i = 0; i < *n; i++)d += v0[i] * v0[i]; 211 if (d < 0.00000001) { 212 *ierror = V_ERROR; 213 return; 214 } 215 d = sqrt(d); 216 for (i = 0; i < *n; i++) v[i] = v0[i] / d; 217 return; 218} 219 220/*ベクトルの差*/ 221void vsub_(double v[], double v1[], double v2[], int *n) 222{ 223 int i; 224 for (i = 0; i < *n; i++)v[i] = v1[i] - v2[i]; 225 return; 226} 227 228/*内積*/ 229double vinpro_(double v1[], double v2[], int *n) 230{ 231 int i; 232 double t = 0.0; 233 for (i = 0; i < *n; i++) t+= v1[i] * v2[i]; 234 return t; 235}

試したこと

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

このエラーメッセージについて教えていただきたいです。

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

episteme

2019/05/04 06:50

何の説明もなされていない。やりなおし。
guest

回答2

0

ベストアンサー

Expression:stream!=nullptr

コード中(ライブラリの中かも)で "stream が nullptr であってはいけない"ってassertに引っかかって
停止しています。心当たりはありませんか?

投稿2019/05/04 06:55

episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

namekuhito

2019/05/04 07:04

返信ありがとうございます。 ファイルから座標のデータを取得しているのですが、fscanf_sで使い方がいまいち理解できていないところがあり、その点が思い当たります。 エラーの内容はstreamが空であるということですか?
episteme

2019/05/04 11:29 編集

です。session は assert に渡された変数名かなにかでしょう。
namekuhito

2019/05/06 02:23

返信が遅くなってしまいすみません。 それは、fscanf_sがうまく動いていないからでしょうか?
episteme

2019/05/06 02:34 編集

おそらくそうでしょう。 fpがNULLなんじゃありませんか? であるなら、fopen_sでファイルを開けそこねていると思われます。
namekuhito

2019/05/06 02:41

分かりました。 今、少し変えて以下のようにしました。 /*点データの入力*/ err = fopen_s(&fp, "a.txt", "r"); if (err == 0) { printf("cannot open point_table.dat\n"); return 0; } else { while (fscanf_s(fp, "%lf%lf", &p[i].x, &p[i].y) != EOF) { p[i].flag = FLAG_OFF; i++; } fclose(fp); }
namekuhito

2019/05/06 02:43

そして、他の方が貼っていただいたURLのように /*点データの入力*/ err = fopen_s(&fp, "a.txt", "r"); if (err == 0) { printf("cannot open point_table.dat\n"); return 0; } ここの、if文は'=='ではなく、'!='に変更するべきでしょうか?
episteme

2019/05/06 03:03 編集

試してみるのにいちいち許可もらうんですか? # fopen_s は成功したら0を返します。
namekuhito

2019/05/06 03:05

すみません 試してみたのですが、printf("cannot open point_table.dat\n");が表示されて、elseにはいってないようでした。
episteme

2019/05/06 03:08

> if ((err = fopen_s(&fp,"point_table.dat.txt", "r")) == '0') { オープンしたいファイルは "point_table.dat.txt" ですか? そんなファイルあるんですか?
namekuhito

2019/05/06 03:22

すみません /*点データの入力*/ err = fopen_s(&fp, "a.txt", "r"); if (err == 0) { printf("cannot open a.txt\n"); return 0; } else { while (fscanf_s(fp, "%lf %lf", &p[i].x, &p[i].y) != EOF) { p[i].flag = FLAG_OFF; i++; } fclose(fp); } に書き直しました。 テキストファイルは、プログラムと同じ場所にあります。
episteme

2019/05/06 03:56

fopen_s は成功したら0を返します。
namekuhito

2019/05/06 04:27

ありがとうございます。プログラムの関数の動作がよく分かってなかったみたいです。 そこで、テキストファイルを変更することで動作しました。 長い間、ありがとうございました。
guest

0

if ((err = fopen_s(&fp,"point_table.dat.txt", "r")) == '0')


if ((err = fopen_s(&fp,"point_table.dat.txt", "r")) != 0)
参考:fopen_sをfopenの代わりに使うときのやりかた

投稿2019/05/04 09:35

編集2019/05/04 09:37
cateye

総合スコア6851

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cateye

2019/05/04 16:11

たぶん、fopen_s()が正常に終わっていない。 Windowsで"point_table.dat.txt"がファイル名として有効かどうか不明?
namekuhito

2019/05/06 02:26

返信が遅くなってしまいすみません。 ファイル名の有効かどうかを確認する方法が分かりません。すみません。 point_table.datのファイル名を変更して、a.txtとかにしたほうが良いでしょうか?
episteme

2019/05/06 03:05

openしたいファイルは point_table.dat.txt ですか? そんなファイルあるんですか? コードにはそう書かれてますよ?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問