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

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

ただいまの
回答率

87.91%

fscanf_s()関数でEOFが返ってこない理由とは?ファイルの終端に達したかをチェックする方法が知りたい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 498
退会済みユーザー

退会済みユーザー

提示コードのコメント部の内部ですがファイルの終端に到達したらEOFを返すことを利用してファイルを最後まで読むのですが無限ループしてしまいます。どうすればいいのでしょうか?リファレンスを見ましたが正しい処理のはずです。
自分のやりたい動作「 無限ループを使ってEOFで抜ける動作を作りファイルを最初から最後まで読む 」という動作を実現したいのですが現状
なぜかEOFでループが抜けず無限ループしてしまいます。(無限ループを抜けません。)

公式リファレンス: https://docs.microsoft.com/ja-jp/cpp/c-runtime-library/reference/fscanf-s-fscanf-s-l-fwscanf-s-fwscanf-s-l?view=msvc-160

//objファイルを読み込み
bool Game::Load_obj(const char* file, std::vector<glm::vec3>& out_vertices, std::vector<glm::vec2>& out_uvs, std::vector<glm::vec3>& out_normals)
{

    std::vector<unsigned int> vertexIndices;    //頂点インデックス
    std::vector<unsigned int> uvIndices;        //UV座標インデックス
    std::vector<unsigned int> normalIndices;    //法線インデックス
    std::vector<unsigned int> out_vertexIndices;

    std::vector<glm::vec3> temp_vertices;
    std::vector<glm::vec2> temp_uvs;
    std::vector<glm::vec3> temp_normals;

    FILE* fp = nullptr;
    fopen_s(&fp, file, "r");    //読み込み専用でファイルを開く

    /*
    //.objファイルを表示
    char str[256] = { 0 };
    if (fp != nullptr) {
        while (fgets(str, 256, fp) != NULL)
        {
            printf("%s", str);
        }
    }
    */
////////////////////////////////////////////////////////////////////////////////////////
    int a = 0;
    if (fp != NULL)
    {
        while (true)
        {
            char lineHeader[256] = { 0 };
            int res = fscanf_s(fp, "%s",lineHeader, (unsigned int )strlen(lineHeader));
            printf("%d\n", &res);

            if (res == EOF)
            {
                break;
            }
            else
            {
////////////////////////////////////////////////////////////////////////////////////
                //ファイル抽出


                //頂点を抽出
                if (strcmp(lineHeader, "v") == 0)
                {
                    glm::vec3 vertex;
                    fscanf_s(fp, "%f %f %f", &vertex.x, &vertex.y, &vertex.z);
                    //out_vertices.push_back(vertex);
                    temp_vertices.push_back(vertex);

                }
                //UV座標を抽出
                else if (strcmp(lineHeader, "vt") == 0)
                {
                    glm::vec2 uv = glm::vec2(0, 0);
                    fscanf_s(fp, "%f %fn", &uv.x, &uv.y);
                    temp_uvs.push_back(uv);
                }
                //法線を抽出
                else if (strcmp(lineHeader, "vn") == 0)
                {
                    glm::vec3 normalize = glm::vec3(0, 0, 0);
                    fscanf_s(fp, "%f %f %fn", &normalize.x, &normalize.y, &normalize.z);
                    temp_normals.push_back(normalize);
                }                
                else if (strcmp(lineHeader, "f") == 0)
                {
        //            std::string vertex1, vertex2, vertex3;
                    unsigned int vertexIndex[3], uvIndex[3], normalIndex[3];

                    int matches = fscanf_s(fp, "%d/%d/%d %d/%d/%d %d/%d/%d",
                        &vertexIndex[0], &vertexIndex[1], &vertexIndex[2],
                        &uvIndex[0], &uvIndex[1], &uvIndex[2],
                        &normalIndex[0], &normalIndex[1], &normalIndex[2]);

                    if (matches != 9)
                    {
                        printf("エラー\n");
                        return false;
                    }

                    vertexIndices.push_back(vertexIndex[0]);
                    vertexIndices.push_back(vertexIndex[1]);
                    vertexIndices.push_back(vertexIndex[2]);

                    uvIndices.push_back(uvIndex[0]);
                    uvIndices.push_back(uvIndex[1]);
                    uvIndices.push_back(uvIndex[2]);

                    normalIndices.push_back(normalIndex[0]);
                    normalIndices.push_back(normalIndex[1]);
                    normalIndices.push_back(normalIndex[2]);
                }
            }
        }


        //頂点を設定
        for (unsigned int i = 0; i < vertexIndices.size(); i++)
        {
            unsigned int vertexIndex = vertexIndices[i];
            glm::vec3 vertex = temp_vertices[vertexIndex - 1];
            out_vertices.push_back(vertex);            
        }

        //UVを設定
        for (unsigned int i = 0; i < uvIndices.size(); i++)
        {
            unsigned int uvIndex = uvIndices[i];
            glm::vec2 uv = temp_uvs[uvIndex - 1];
            out_uvs.push_back(uv);
        }

        //法線を設定
        for (unsigned int i = 0; i < normalIndices.size(); i++)
        {
            unsigned int normalIndex = normalIndices[i];
            glm::vec3 normalize = temp_normals[normalIndex - 1];
            out_normals.push_back(normalize);
        }



//        printf(".objファイル読み込み完了!\n");
        return true;
    }
    else
    {
        printf("ファイルが読めませんでした。\n");
        return false;
    }
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • 退会済みユーザー

    2020/12/31 13:10

    複数のユーザーから「やってほしいことだけを記載した丸投げの質問」という意見がありました
    「質問を編集する」ボタンから編集を行い、調査したこと・試したことを記入していただくと、回答が得られやすくなります。

回答 2

+2

 char lineHeader[256] = { 0 };
 int res = fscanf_s(fp, "%s",lineHeader, (unsigned int )strlen(lineHeader));

fscanf_s に渡している strlen(lineHeader) は何を意図したものですか? 何を渡したいのですか?
lineHeaderの大きさ(サイズ)を渡したつもりなら、それはマチガイ。
stelen(lineHeader) の戻り値がいくつか調べた?

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

checkベストアンサー

+1

char lineHeader[256] = { 0 };
int res = fscanf_s(fp, "%s",lineHeader, (unsigned int )strlen(lineHeader));

ここで、strlenを使うのは間違いです
strlen(lineHeader)の結果は0にしかなりません

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/12/31 11:27 編集

    sizeof(lineHeader);にして見たのですがそれでもアクセスエラーが発生してしまいます。この場合どうすればいいのでしょうか? 追記 printf();デバックという行為を忘れていました。

    キャンセル

  • 2020/12/31 11:31

    int res = fscanf_s(fp, "%s",lineHeader, (unsigned int )sizeof(lineHeader));
    ではだめですか?

    キャンセル

  • 2020/12/31 11:36

    invalid vector subscript
    どうやらベクターで無効な添字と表示されているのでここではないということなのでベストアンサーとさせていただきます。

    キャンセル

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

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

関連した質問

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

  • トップ
  • C++に関する質問
  • fscanf_s()関数でEOFが返ってこない理由とは?ファイルの終端に達したかをチェックする方法が知りたい