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

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

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

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

C++

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

Q&A

解決済

2回答

2725閲覧

fscanf_s()関数でアクセスエラーが出る原因が知りたい。

退会済みユーザー

退会済みユーザー

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

C++

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

0グッド

0クリップ

投稿2021/12/29 02:43

編集2021/12/29 03:10

提示コードですが下記の.objファイルのv要素の読み込みで///コメント部内部のパターン1、パターン2、ともにアクセスエラーが発生してしまいます。またコメント部のコードは普通に実行できます。なぜ二つはアクセスエラーになるのでしょうか?

参考サイト: https://programming.pc-note.net/c/file4.html

// ##################################### .objファイル読み込み ##################################### std::shared_ptr<std::vector<FrameWork::Vertex>> FrameWork::GetVertex(const char* path) { #define LINE_BUFFER ((int)(500)) //FrameWork::Object_File object; std::vector<FrameWork::Vertex> polygon; std::vector<int> vertexIndex; std::vector<int> uvIndex; std::vector<int> normalIndex; std::vector<glm::vec3> vertex; std::vector<glm::vec2> uv; std::vector<glm::vec3> normal; FILE* file; fopen_s(&file, path, "r"); bool b = false; if (file == NULL) { std::cerr << ".objファイルが開けません: " << path << std::endl; assert(0); } else { FrameWork::vertex temp; bool b = false; while (true) { char line[500] = {'\0'}; int res = fscanf_s(file, "%s", line,LINE_BUFFER); if (res == EOF) { break; } if (strcmp(line, "o") == 0) { char str[LINE_BUFFER] = {'\0'}; fscanf_s(file, "%s", str,LINE_BUFFER); printf("%s\n",str); if (b == true) { polygon.push_back(temp); temp.attribute.resize(0); } if (b == false) { b = true; } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// else if (strcmp(line, "v") == 0) { //パターン1 char vert[3][LINE_BUFFER] = { { '\0' } ,{ '\0' } ,{ '\0' } }; fscanf_s(file, "%s %s %s ", vert[0], vert[1], vert[2]); //パターン2 glm::vec3 v = glm::vec3(0, 0, 0); fscanf_s(file, "%f %f %f", v.x, v.y, v..z); /* glm::vec3 v; char vert[LINE_BUFFER] ={'\0'}; fscanf_s(file, "%s", &vert, LINE_BUFFER); v.x = (float)atof(vert); fscanf_s(file, "%s", &vert, LINE_BUFFER); v.y = (float)atof(vert); fscanf_s(file, "%s", &vert, LINE_BUFFER); v.z = (float)atof(vert); vertex.push_back(v); printf("v %f %f %f \n", v.x, v.y, v.z); */ } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// else if (strcmp(line, "vt") == 0) { glm::vec2 u; char vert[LINE_BUFFER] = { '\0' }; fscanf_s(file, "%s", &vert, LINE_BUFFER); u.x = (float)atof(vert); fscanf_s(file, "%s", &vert, LINE_BUFFER); u.y = (float)atof(vert); printf("vt %f %f \n", u.x, u.y); uv.push_back(u); } else if (strcmp(line, "vn") == 0) { glm::vec3 norm; fscanf_s(file, "%f %f %fn", &norm.x, &norm.y, &norm.z); normal.push_back(norm); } else if (strcmp(line, "f") == 0) { unsigned int v[3], u[3], n[3]; int matches = fscanf_s(file, "%d/%d/%d %d/%d/%d %d/%d/%dn", &v[0], &u[0], &n[0], &v[1], &u[1], &n[1], &v[2], &u[2], &n[2]); vertexIndex.push_back(v[0]); vertexIndex.push_back(v[1]); vertexIndex.push_back(v[2]); uvIndex.push_back(u[0]); uvIndex.push_back(u[1]); uvIndex.push_back(u[2]); normalIndex.push_back(n[0]); normalIndex.push_back(n[1]); normalIndex.push_back(n[2]); } else if (strcmp(line, "usemtl") == 0) { char str[LINE_BUFFER]; char number[LINE_BUFFER]; fscanf_s(file, "%s", str, LINE_BUFFER); strncpy_s(number, str + strlen("Material."), LINE_BUFFER); int num = atoi(number); printf("newmtl Material.%d\n",num); temp.materialNumber = num; } else if (strcmp(line, "s") == 0) { char str[LINE_BUFFER]; char number[LINE_BUFFER]; fscanf_s(file, "%s", str, LINE_BUFFER); strncpy_s(number, str, LINE_BUFFER); int num = atoi(number); printf("s %d\n", num); temp.shading = num; //temp.materialNumber = num; } } for (unsigned int i = 0; i < vertexIndex.size(); i++) { unsigned int vi = vertexIndex[i]; unsigned int ui = uvIndex[i]; unsigned int ni = normalIndex[i]; glm::vec3 v = vertex[vi - 1]; glm::vec2 u = uv[ui - 1]; glm::vec3 n = normal[ni - 1]; FrameWork::VertexAttribute attrib; attrib.position[0] = v.x; attrib.position[1] = v.y; attrib.position[2] = v.z; attrib.uv[0] = u.x; attrib.uv[1] = u.y; attrib.normal[0] = n.x; attrib.normal[1] = n.y; attrib.normal[2] = n.z; temp.attribute.push_back(attrib); } } return std::make_shared<std::vector<FrameWork::Vertex>>(polygon); }
.objファイル
# Blender v2.83.4 OBJ File: 'cloud.blend' # www.blender.org mtllib cloud.mtl o 7_armguard_0_0_0 v 0.267984 1.136365 -0.005862 v 0.181013 1.093678 -0.007669 v 0.309287 1.067712 0.092497 v 0.214476 1.021204 0.097445 v 0.312156 1.068274 -0.103130 v 0.217549 1.021802 -0.112007 v 0.379954 1.091695 -0.003916 v 0.173889 0.971327 -0.008270 vt 0.000000 2.000000 vt 0.000000 2.000000 vt 0.000000 2.000000 vt 0.000000 2.000000 vt 0.000000 2.000000 vt 0.000000 2.000000 vt 0.000000 2.000000 vt 0.000000 2.000000 vn -0.1063 0.9943 0.0016 vn -0.7802 0.6254 -0.0110 vn -0.0802 0.8085 0.5830 vn -0.6428 0.5196 0.5629 vn -0.0596 0.8122 -0.5804 vn -0.6244 0.5238 -0.5795 vn 0.3704 0.9288 0.0095 vn -0.9982 0.0582 -0.0151 usemtl Material.025 s 1 f 1/1/1 2/2/2 3/3/3 f 3/3/3 2/2/2 4/4/4 f 2/2/2 1/1/1 5/5/5 f 6/6/6 2/2/2 5/5/5 f 5/5/5 1/1/1 7/7/7 f 1/1/1 3/3/3 7/7/7 f 2/2/2 8/8/8 4/4/4 f 8/8/8 2/2/2 6/6/6

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

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

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

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

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

y_waiwai

2021/12/29 02:47

コードを全文提示しよう。 不足すぎて分けわかりません
guest

回答2

0

fscanf_s、_fscanf_s_l、fwscanf_s、_fwscanf_s_l | Microsoft Docs

とりあえず、正式なドキュメントを読もう。
むちゃくちゃしても動きませんよ

投稿2021/12/29 02:50

y_waiwai

総合スコア88042

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

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

退会済みユーザー

退会済みユーザー

2021/12/29 03:18

公式リファレンスのサンプルコードにある通り第三引数にはsize_t型が必要でしたよって fscanf_s(file, "%f %f %f", &v.x,&v.y,&v.z,(size_t)LINE_BUFFER); としました。正解でしょうか?
guest

0

ベストアンサー

3点ほど気になる点があったので、書いておきます。

■ 気になった箇所
・文字列の比較について
・fscanf_s() の使い方
・そもそも fscanf_s() → sscanf_s() を使うべきでは?

■ 文字列の比較について

c++

1else if (strcmp(line, "v") == 0)

これだと、完全一致(lineが"v")の場合にしか処理されません。

部分一致で比較したいのであれば、

c++

1// 先頭の2文字でレコードの種類を判別 2if (strncmp(line, "v ", 2) == 0) {

とした方が良いかと思います。

■ fscanf_s() の使い方

v 0.267984 1.136365 -0.005862

に対して "%s %s %s" の書式で参照すると

[v][0.267984][1.136365]

が取得されてしまいます。
書式としては "v %s %s %s" が望ましいかと思います。

また、fscanf_s() では %s を使用する毎にバッファのサイズを指定する必要があります。

c++

1//パターン1 2char vert[3][LINE_BUFFER] = { { '\0' } ,{ '\0' } ,{ '\0' } }; 3//fscanf_s(file, "%s %s %s ", vert[0], vert[1], vert[2]); 4fscanf_s(file, "v %s %s %s ", vert[0], _countof(vert[0]), vert[1], _countof(vert[1]), ​vert[2], _countof(vert[2])); 5 6//パターン2 7glm::vec3 v = glm::vec3(0, 0, 0); 8//fscanf_s(file, "%f %f %f", v.x, v.y, v.z); 9fscanf_s(file, "v %f %f %f", &v.x, &v.y, &v.z);

■ そもそも fscanf_s() → sscanf_s() を使うべきでは?

fscanf_s() を実行する毎に新たにファイルから1行読み込まれます。
既に文字列 line を取得する為に1行読み込まれているはずなので、
再度 fscanf_s() を実行した場合は、次の行が読み込まれることになります。
ここで使いたいのは既に読み込んでいる line の情報になる為、sscanf_s() を使うべきかと思います。

c++

1//パターン1 2char vert[3][LINE_BUFFER] = { { '\0' } ,{ '\0' } ,{ '\0' } }; 3sscanf_s(line, "v %s %s %s ", vert[0], _countof(vert[0]), vert[1], _countof(vert[1]), ​vert[2], _countof(vert[2])); 4 5//パターン2 6glm::vec3 v = glm::vec3(0, 0, 0); 7sscanf_s(line, "v %f %f %f", &v.x, &v.y, &v.z);

投稿2021/12/29 04:08

cx20

総合スコア4648

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

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

cx20

2021/12/29 07:02

あぁ、ごめんなさい。一部、自分が早合点してました。 > int res = fscanf_s(file, "%s", line,LINE_BUFFER); line が1行分読み込まれているものだと思いましたが、 ヘッダ部とデータ部で、別れて読み込まれている、ということのようですね。 であれば、strcmp() でも大丈夫そうです。 <参考> ■ opengl-tutorials の objloader.cpp https://github.com/opengl-tutorials/ogl/blob/master/common/objloader.cpp
episteme

2021/12/29 09:51 編集

一行分が読まれているような変数名:line が悪い。token/word 等に改めよ。 さもなくば line にはちゃんと一行分読め。
cx20

2021/12/29 11:00

変数名「line」は完全にひっかけ問題ですね・・ 当初の質問には line の読み込み部分の箇所が記載されていなかった為、 てっきり fgets() で1行読み込んでいるのかと思ってました。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問