0

我正在尝试打开一个我将在 C++ 中使用的 json 文件。我之前成功使用的代码无法打开文件。我在 Windows 10 Pro 上使用 Visual Studio 2017 和现代 C++ 版本 3.5.0 的 JSON。

我有一个非常简单的函数,它应该打开一个文件作为 json 对象的输入。它似乎打开了文件,但在将其写入 json 对象时中止。最初要打开的文件位于另一个目录中,但我在测试时将它移到了与可执行文件相同的目录中......但这没有帮助。

这是失败的非常短的功能:

json baselineOpenAndRead(string fileName) //passed string used for filename 
{

    json baseJObject;
    cout << "we have a baseJObject" << endl;

    //ifstream inFileJSON("test_file.json");  // Making this explicit made no difference
    ifstream inFileJSON;
    inFileJSON.open("test_file.json", ifstream::in); 
    cout << "we have opened json inFileJSON" << endl; // get here


    inFileJSON >> baseJObject;
    cout << " Can direct inFileJSON into baseJObject" << endl; //never get here; the app aborts.
    inFileJSON.close();
    return baseJObject;
}

这似乎与 nlohmann 网站上的示例基本相同:

// read a JSON file
std::ifstream i("file.json");
json j;
i >> j;

我只是希望这会打开 json 文件,将其加载到对象中,然后返回对象。相反,它只是退出。

感谢您的任何想法...即,我做错了什么?(我会忽略它之前的工作......也许我错过了一些东西)。

--铝

根据要求,这是一个最小的可重现示例,但它需要 nlohmann 的 json.hpp 才能编译:

#include <iostream>
#include <fstream>
#include "json.hpp"

using json = nlohmann::json;
using namespace std;

string fileName;
json baselineOpenAndRead(string);

int main(int argC, char *argV[])
{
    json baseJObject;

    if (argC != 2) // check to make sure proper number of arguments are given.
    {
        cout << "\n\nFilename needed...";
        exit(1); // number of arguments is wrong - exit program
    }
    else
    {
        fileName = argV[1];
        baseJObject = baselineOpenAndRead(fileName); // opens and reads the Base Line JSON file
        cout << "baseJObject returned" << endl;
    }
    return 0;
}

json baselineOpenAndRead(string fileName) // 
{
    cout << "File name: " << fileName << endl;
    json baseJObject;
    cout << "we have a baseJObject" << endl;

    ifstream inFileJSON(fileName);

    if (inFileJSON.is_open())
    {
        cout << "file open..." << endl;
        if (nlohmann::json::accept(inFileJSON))
        {
            cout << "valid json" << endl;
            try { inFileJSON >> baseJObject; }
            catch (const std::exception &e) { std::cout << e.what() << '\n'; throw; }
        }
        else
        {
            cout << "not valid json" << endl;
        }
    }
    else
    {
        cout << "file not really open" << endl;
    }
    inFileJSON >> baseJObject;
    cout << " We can echo inFileJSON into baseJObject" << endl;
    inFileJSON.close();
    return baseJObject;
}

我用这个 json 文件对其进行了测试:

{
    "people": [{
            "name": "Scott",
            "website": "stackabuse.com",
            "from": "Nebraska"
        },
        {
            "name": "Larry",
            "website": "google.com",
            "from": "Michigan"
        },
        {
            "name": "Tim",
            "website": "apple.com",
            "from": "Alabama"
        }
    ]
}

当我运行它时,将上面的 json 作为 data.json 传递,我得到以下输出,然后退出:

./Test_json data.json
File name: data.json
we have a baseJObject
file open...
valid json
[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal

没有尝试,它就退出了。它永远不会过去inFileJSON >> baseJObject;

另一个似乎有效的尝试,但为什么呢?

好的。我用相同的 main 尝试了这个(唯一的变化是在函数中):

json baselineOpenAndRead(string fileName) // 
{

    json baseJObject;
    string filePath = "../baselines/" + fileName;
    cout << "filePath: " << filePath << endl;
    ifstream inFileJSON(fileName);
    //baseJObject = json::parse(inFileJSON);
    inFileJSON >> baseJObject;
    cout << baseJObject << std::endl;
    return baseJObject;
}

这在我看来基本相同。我尝试在原始文件和这个文件中都使用 ifstream inFileJSON(fileName.c_str()) 。原来的继续失败,这个继续工作。对不起,这太长了,但我无法从评论中得到体面的格式......我应该试着回答我自己的问题吗?

4

1 回答 1

0

我想我有这个。我相信我最初的问题是由我的一个 json 测试文件中的错误“,”引起的。随后,if (inFileJSON.is_open)工作,但if (nlohmann::json::accept(inFileJSON)失败并导致相同(或类似)错误。我认为我需要 c_str() 文件可执行文件目录之外的路径,但它似乎并没有以一种或另一种方式产生影响。我取出了接受(),这段代码似乎始终如一地工作:

json baselineOpenAndRead(string fileName) // 
{
    json baseJObject;
    cout << "we have a baseJObject" << endl;
    string filePath = "../baselines/" + fileName;
    cout << "filePath: " << filePath << endl;
    //ifstream inFileJSON(filePath.c_str());
    ifstream inFileJSON(filePath);

    if (inFileJSON.is_open())
    {
        cout << "File is open." << endl;
        inFileJSON >> baseJObject;
        cout << baseJObject << std::endl;
        inFileJSON.close();
        return baseJObject;
    }
    else
    {
        cout << "File not open." << endl;
        exit(1);
    }
}

感谢大家的帮助。我很感激。

--铝

于 2019-10-15T02:16:23.180 回答