0

I want to replace a parameter in my JSON file with a string. My script scrubs a json file for all 'dialogue' strings, exports them to a txt file where they can be edited and than reimports them back into the json file. The problem I am getting is that, while adding the string back into the json, additional characters are added.

Say I wanted to replace a dialogue from "Hello" To Hello there".
With the example code the original json... "\{Hello " when exported to a txt file becomes "\{Hello there" but, when reimported back into the json becomes ""\\{Hello there"" when the expected result should be "\{Hello there"

I also tried to put asString() for the root line but that didn't work either as i've found on other forums.

Edit: Test code to use. Create a file called "Map130.json"

{   
"parameters": "\"Hello, this is a test line.. "                     
}

select option 1. Edit the generated text file if needed. Then run the program again and select option 2.

// jsonExtractor.cpp : This file contains the 'main' function. Program execution begins and ends there.
//

#include <iostream>
#include <json/value.h>
#include <json/json.h>
#include <fstream>
#include <string>
#include <locale>         // std::wstring_convert
#include <codecvt>        // std::codecvt_utf8
#include <cstdint>        // std::uint_least32_t
using namespace std;




int main()
{
    bool doDialogue;
    bool writeToTxt = true;     //write dialouge (and page/ scene num) to a text file.

                                 //compare the json dialouge (and page/scene num) to txt file. 
    bool compareLines = false;   //If the line counts match, continue. If not stop. seems like it might clear the txt file if this fails...
    bool newJson = false; //compares json to text and makes a new json
    int jsonLine = 0;
    int cReadWrite;
    int currentMapNumInt;
    string currentMapNumStr;

    std::cout << "1 for write to txt file from json. 2 for txt to overwrite json .";
    cin >> cReadWrite;

    if (cReadWrite == 1) {
        writeToTxt = true;
        compareLines = false;
        newJson = false;
    }
    else if (cReadWrite == 2) {
        writeToTxt = false;
        compareLines = true;
        newJson = true;
    }
    else {std::cerr << "WARNING!!! the 1 or 2 thingy... you didnt enter it.\n"; return EXIT_FAILURE;}

        cout << currentMapNumStr;

        Json::Value root;
        Json::Reader reader;
        Json::StreamWriterBuilder builder;
        builder["emitUTF8"] = true;
        std::unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter());
        ifstream  file("...Map130.json"); //pg Jsonfile

        reader.parse(file, root);
        cout << root << endl;
        Json::Value events = root["parameters"];
        cout << events << endl;

        string dialogue;
        Json::Value tempDialogue;
        if (newJson && writeToTxt) {
            std::cerr << "WARNING!!! newJson and writeToTxt cannot both be true at the same time.\n";
            return EXIT_FAILURE;
        }
        if (compareLines && writeToTxt) {
            std::cerr << "WARNING!!! compareLines and writeToTxt cannot both be true at the same time.\n";
            return EXIT_FAILURE;
        }

        std::fstream txtFileIn;
        if (newJson) txtFileIn.open("...Map130.txt"); //new txt file
        std::ofstream txtFileOut;
        if (writeToTxt) txtFileOut.open("...Map130.txt");//same as above
        int numOfLines = std::count(std::istreambuf_iterator<char>(txtFileIn), std::istreambuf_iterator<char>(), '\n');
        string txtLine;
        wstring convertDialogue;
        if (newJson)   txtFileIn.seekg(0);
        std::ofstream convertedFile;
        if (newJson) convertedFile.open("...Map130.json");//new json


                        tempDialogue = events;//.asString().substr(1, tempDialogue.size() - 1);
                        cout << "Dialouge" << tempDialogue << endl;
                        if (writeToTxt) {
                            writer->write(tempDialogue, &txtFileOut);
                            txtFileOut << endl;
                        }

                        if (newJson) {
                            getline(txtFileIn, txtLine);
                           
                            root["parameters"] = txtLine;
                        }

        if (newJson) writer->write(root, &convertedFile);
        file.close();
        txtFileIn.close();
        convertedFile.close();
        cout << endl << "done";
}
2
  • Can you provide a minimal reproducible example with string streams instead of file streams? Commented Jul 7, 2023 at 21:51
  • Updated added example. Commented Jul 10, 2023 at 19:23

1 Answer 1

0

The JSON::Value events contains the raw value with double quotes and escape character. You can get the actual value with events.asString().

You have the same problem with tempDialogue and the first argument of writer->write. Both have type JSON::Value and are printed as raw values with double quotes and escape characters. Convert the JSON::Values to strings with asString and write the strings into the file.

#include <algorithm>
#include <codecvt> // std::codecvt_utf8
#include <cstdint> // std::uint_least32_t
#include <fstream>
#include <iostream>
#include <locale> // std::wstring_convert
#include <string>
#include <json/value.h>
#include <json/json.h>

int main()
{
    bool doDialogue;
    bool writeToTxt = true; // write dialouge (and page/ scene num) to a text file.

    // compare the json dialouge (and page/scene num) to txt file.
    bool compareLines = false; // If the line counts match, continue. If not stop. seems like it might clear the txt file if this fails...
    bool newJson = false;      // compares json to text and makes a new json
    int jsonLine = 0;
    int cReadWrite;
    int currentMapNumInt;
    std::string currentMapNumStr;

    std::cout << "1 for write to txt file from json. 2 for txt to overwrite json .";
    std::cin >> cReadWrite;

    if (cReadWrite == 1)
    {
        writeToTxt = true;
        compareLines = false;
        newJson = false;
    }
    else if (cReadWrite == 2)
    {
        writeToTxt = false;
        compareLines = true;
        newJson = true;
    }
    else
    {
        std::cerr << "WARNING!!! the 1 or 2 thingy... you didnt enter it.\n";
        return EXIT_FAILURE;
    }

    std::cout << currentMapNumStr;

    Json::Value root;
    Json::Reader reader;
    Json::StreamWriterBuilder builder;
    builder["emitUTF8"] = true;
    std::unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter());
    std::ifstream file("Map130.json"); // pg Jsonfile

    reader.parse(file, root);
    std::cout << root << std::endl;
    Json::Value events = root["parameters"];
    std::cout << events.asString() << std::endl;

    std::string dialogue;
    Json::Value tempDialogue;
    if (newJson && writeToTxt)
    {
        std::cerr << "WARNING!!! newJson and writeToTxt cannot both be true at the same time.\n";
        return EXIT_FAILURE;
    }
    if (compareLines && writeToTxt)
    {
        std::cerr << "WARNING!!! compareLines and writeToTxt cannot both be true at the same time.\n";
        return EXIT_FAILURE;
    }

    std::fstream txtFileIn;
    if (newJson)
        txtFileIn.open("Map130.txt"); // new txt file
    std::ofstream txtFileOut;
    if (writeToTxt)
        txtFileOut.open("Map130.txt"); // same as above
    int numOfLines = std::count(std::istreambuf_iterator<char>(txtFileIn), std::istreambuf_iterator<char>(), '\n');
    std::string txtLine;
    std::wstring convertDialogue;
    if (newJson)
        txtFileIn.seekg(0);
    std::ofstream convertedFile;
    if (newJson)
        convertedFile.open("Map130.json"); // new json

    tempDialogue = events; //.asString().substr(1, tempDialogue.size() - 1);
    std::cout << "Dialouge" << tempDialogue.asString() << std::endl;
    if (writeToTxt)
    {
        txtFileOut << tempDialogue.asString() << std::endl;
    }

    if (newJson)
    {
        getline(txtFileIn, txtLine);

        root["parameters"] = txtLine;
    }

    if (newJson)
        writer->write(root, &convertedFile);
    file.close();
    txtFileIn.close();
    convertedFile.close();
    std::cout << std::endl
              << "done";
}

Either write the line and read the line, or write JSON and read JSON. In your current code you write JSON, read the line and serialize it to JSON. That doesn't work, because it adds quotation marks and escape characters.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.