XML Parser not showing informations C++ - c++

I am using TinyXML2 and I got some strange problem. So It seems it work because I dont have any crashes but when I want to output one of the value I got I have nothing , if someone know why ?
I already used tinyxml2 and it was working but here maybe the XML is strange?
#include <iostream>
#include "tinyxml2/tinyxml2.cpp"
#include "../Inc/classConfigCtx.h"
#include "../Inc/globalDefine.h"
using namespace tinyxml2;
int main() {
std::cout << "Hello World!";
XMLDocument doc;
doc.LoadFile( "NetworkConfig.xml" );
int AppliMsgPort_;
const char * portAppli;
const char * IPtemp;
XMLElement * pRootElement =doc.RootElement()->FirstChildElement();
portAppli=pRootElement->FirstChildElement()->GetText();
std::cout<<portAppli;
return 0;
}
and my XML
<configuration>
<operational_00001000><name value="100.CBD" /><radio_1><type value="Net" /><ip value="10.36.1.1" /><port_s value="50010" /><port_r value="50100" /><radioID value="10040" /></radio_1></operational_00001000>
<operational_00001005><name value="100.LOG" /><radio_1><type value="Net" /><ip value="10.26.2.1" /><port_s value="50000" /><port_r value="50000" /><radioID value="1000005" /></radio_1></operational_00001005>
</configuration>

Related

Qt utf-16 output shows question marks in Windows cmd and powershell -- with minimum reproducible example in C++

Previously, I have asked Qt translations in C++ project are rendered as question marks in cmd and powershell question. The point of the question was that the help message of .\app -h, translated to Cyrillic, is rendered as ?????????.
Since then, I discovered that in https://github.com/RSATom/Qt/blob/master/qtbase/src/corelib/tools/qcommandlineparser.cpp, the Qt messages are printed with qInfo("%ls", qUtf16Printable(message)) on Windows.
In cmd.exe or poweshell.exe I get question marks ?????????, when trying to output a Cyrillic message this way.
I tried to change the font of cmd.exe and powershell.exe to Lucida Console and to execute chcp 10000 (as proposed here UTF-16 on cmd.exe), but this does not help.
Here is the minimum reproducible example:
// > cl main.cpp /I C:\Qt\5.12.12\msvc2017_64\include
// > link main.obj /LIBPATH C:\Qt\5.12.12\msvc2017_64\lib\Qt5Core.lib
#include "QtCore/QtGlobal"
#include "QtCore/QString"
int main()
{
qInfo("%ls", qUtf16Printable("Привет"));
return 0;
}
// > main.exe
// ??????
I would really appreciate any help. There are two problems here. The first: how can I use QCommandLineParser under Windows. The second: if QCommandLineParser (using qInfo("%ls", qUtf16Printable(message))) is okay and not a bug, then how can I make cmd show it all right.
I don't pretend on the answer, but on Windows for Unicode console output you should do something similar to:
#include <QDebug>
#include <iostream>
#include <string>
#include <fcntl.h>
#include <io.h>
#include <stdio.h>
void myMessageOutput( QtMsgType type, const QMessageLogContext & context, const QString & msg )
{
Q_UNUSED( context );
std::wcout << msg.toStdWString() << std::endl;
if( type == QtFatalMsg )
abort();
}
int main()
{
_setmode( _fileno( stdout ), _O_U16TEXT );
qInstallMessageHandler( myMessageOutput );
const std::wstring rs = L"Привет";
const auto s = QString::fromStdWString( rs );
std::wcout << s.toStdWString() << std::endl;
qDebug() << s;
qInfo() << s;
return 0;
}
Accidentally I found the solution. You should create following manifest file for your executable:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<application>
<windowsSettings>
<activeCodePage xmlns="http://schemas.microsoft.com/SMI/2019/WindowsSettings">UTF-8</activeCodePage>
</windowsSettings>
</application>
</assembly>
Let it will be named as app.manifest. In CMake project just add app.manifest into sources of your executable.
In the main() function add two lines of code:
#include <Windows.h>
int main( int argc, char ** argv )
{
SetConsoleCP( GetACP() );
SetConsoleOutputCP( GetACP() );
}
And voila...
Printing should be done using UTF-8, so:
// 1 - works.
QTextStream s( stdout );
s << QString( "Вот оно!!!\n" ) << Qt::flush;
// 2 - works.
fputs( qPrintable( QString( "Опа-на...\n" ) ), stdout );
// 3 - works.
std::cout << u8"std::cout работает!!!\n";
// 4 - DOES NOT work.
std::wcout << L"wcout НЕ работает!!!\n";

Validating if a JSON object is present in a file with nlohmann JSON C++ library

I have a project where I import JSON files to setup global variables. There are various possibilities to the JSON object names in the files, so I want to know how can I check if an object is there or not. The way I tried to do it (with an if statement as shown below) causes an error
The program '..\..\build\jacky.exe' has exited with code 3 (0x00000003).
So it does not work at all. Is there a way to do this? Thanks!
#include <iostream>
#include <string>
#include <fstream>
#include "json.hpp" // json library by nlohmann
std::ifstream gJsonFile;
nlohmann::json j;
int var;
int main(int argc, char *argv[])
{
gJsonFile.open(/* whatever json file path */, std::ifstream::in);
if (gJsonFile.is_open())
{
j << gJsonFile;
if (j["Shirt Size"]) // causes exit with code 3 if false
var = (j["Shirt Size"]);
else
var = (j["AB Circumference"]);
}
}
if ( j.find("Shirt Size") != j.end() )
Or (this will create an entry if it does not already exist)
if ( !j["Shirt Size"].is_null() )

I invoke LSCopyApplicationURLsForURL() using C++, but get a segment fault

I want to write a C++ program to get associated applications which are suitable to open specified file. I find the LSCopyApplicationURLsForURL API, and create a command line C++ application by XCode.
But after running this program, I always get segment fault. XCode shows EXEC_BAD_ACCESS(code=1, address....) error.
I also tryied running it from sudo, but the same result. What is the problem?
The code:
#include <iostream>
#include <objc/objc.h>
#include <objc/objc-runtime.h>
#include <CoreFoundation/CoreFoundation.h>
#include <CoreServices/CoreServices.h>
using namespace std;
int main(int argc, const char * argv[]) {
auto url = CFURLRef("file:///Users/efan/src/a.cpp");
auto ret = LSCopyApplicationURLsForURL(url, kLSRolesAll);
cout << ret << endl;
return 0;
}
Try creating your CFURLRef using one of the proper CFURLCreate* methods. See "Creating a CFURL" here.
For example:
auto tempStringURL = CFStringCreateWithCString(nullptr, "/Users/efan/src/a.cpp", kCFStringEncodingUTF8);
auto url = CFURLCreateWithFileSystemPath(nullptr, tempStringURL, kCFURLPOSIXPathStyle, FALSE);
auto ret = LSCopyApplicationURLsForURL(url, kLSRolesAll);
You need to Release the "Created" variables to clean up memory.

Pantheios write to extenal file

I looked around and I couldn't find the answer to how exactly to do this. I am trying to use Pantheios for logging and I want to write to an external file (otherwise whats the point). I am following one of the examples provided but It doesn't seem to be making the log file anywhere. Here is the code:
Edit: Also pantheios_be_file_setFilePath is returning -4 (PANTHEIOS_INIT_RC_UNSPECIFIED_FAILURE) so thats.....not helpful
#include "stdafx.h"
#include <pantheios/pantheios.hpp>
#include <pantheios/implicit_link/core.h>
#include <pantheios/implicit_link/fe.simple.h>
#include <pantheios/implicit_link/be.WindowsConsole.h>
#include <pantheios/implicit_link/be.file.h>
#include <pantheios/frontends/fe.simple.h>
#include <pantheios/backends/bec.file.h>
#include <pantheios/inserters/args.hpp>
PANTHEIOS_EXTERN_C const PAN_CHAR_T PANTHEIOS_FE_PROCESS_IDENTITY[] = PANTHEIOS_LITERAL_STRING("LogTest");
int _tmain(int argc, _TCHAR* argv[])
{
try
{
pantheios_be_file_setFilePath(PANTHEIOS_LITERAL_STRING("testlogforme.log"), PANTHEIOS_BE_FILE_F_TRUNCATE, PANTHEIOS_BE_FILE_F_TRUNCATE, PANTHEIOS_BEID_ALL);
pantheios::log(pantheios::debug, "Entering main(", pantheios::args(argc,argv, pantheios::args::arg0FileOnly), ")");
pantheios::log_DEBUG("debug yo");
pantheios::log_INFORMATIONAL("informational fyi");
pantheios::log_NOTICE("notice me!");
pantheios::log_WARNING("warning!!");
pantheios::log_ERROR("error omg");
pantheios::log_CRITICAL("critical!!!");
pantheios::log_ALERT("alert mang");
pantheios::log_EMERGENCY("EMERGENCY!!!!!");
pantheios_be_file_setFilePath(NULL, PANTHEIOS_BEID_ALL);
system("pause");
return EXIT_SUCCESS;
}
catch(std::bad_alloc&)
{
pantheios::log_ALERT("out of memory");
}
catch(std::exception& x)
{
pantheios::log_CRITICAL("Exception: ", x);
}
catch(...)
{
pantheios::puts(pantheios::emergency, "Unexpected unknown error");
}
return EXIT_FAILURE;
}
Maybe I'm not calling a method or maybe its not being saved to a good location?
It turns out that some of the examples out there for pantheios are incorrect. You DO need to call pantheios_init() even if you are in C++. Here Is the example I got to work after deleting all my code and implementing an example that works.
// Headers for main()
#include <pantheios/pantheios.hpp>
#include <pantheios/backends/bec.file.h>
// Headers for implicit linking
#include <pantheios/implicit_link/core.h>
#include <pantheios/implicit_link/fe.simple.h>
#include <pantheios/implicit_link/be.file.h>
PANTHEIOS_EXTERN_C const char PANTHEIOS_FE_PROCESS_IDENTITY[] = "testLOL";
int main()
{
if(pantheios::pantheios_init() < 0)
{
return 1;
}
pantheios::log_NOTICE("log-1"); // save until log file set
pantheios_be_file_setFilePath("mylogfile.log"); // sets log file; write "log-1" stmt
pantheios::log_NOTICE("log-2"); // write "log-2" stmt
pantheios_be_file_setFilePath(NULL); // close "mylogfile"
pantheios::log_NOTICE("log-3"); // save until log file set
pantheios_be_file_setFilePath("mylogfile2.log"); // sets log file; write "log-3" stmt
pantheios::log_NOTICE("log-4"); // write "log-4" stmt
//system("pause");
return 0;
} // closes "mylogfile2" during program closedown
I found the example on a different post on stack overflow but like I said, the built in examples do not work.

UTF-8 and TinyXML

For some reason I can not read data from a xml file properly.
For example instead of "Schrüder" I get something like "Schrüder".
My code:
tinyxml2::XMLDocument doc;
bool open(string path) {
if(doc.LoadFile(path.c_str()) == XML_SUCCESS)
return true;
return false;
}
int main() {
if(open("C:\\Users\\Admin\\Desktop\\Test.xml"))
cout << "Success" << endl;
XMLNode * node = doc.RootElement();
string test = node->FirstChild()->GetText();
cout << test << endl;
return 0;
}
Part of XML:
<?xml version="1.0" encoding="UTF-8"?>
<myXML>
<my:TXT_UTF8Test>Schrüder</my:TXT_UTF8Test>
</myXML>
Notice that if I convert it to ANSI and change the encoding type to "ISO-8859-15" it works fine.
I read that something like "LoadFile( filename, TIXML_ENCODING_UTF8 )" should help. However that's not the case (error: Invalid arguments, it just expects a const char). I have the latest version of TinyXML2 (I guess?). I downloaded it just a couple minutes ago from https://github.com/leethomason/tinyxml2.
Any ideas?
Edit: When I write the string to a .xml or .txt file it works fine. There might be some problem with the eclipse ide console. Anyway, when I try to send the string via E-Mail, I also get the same problems. Here's the MailSend script:
bool sendMail(std::string params) {
if( (int) ShellExecute(NULL, "open", "H:\\MailSend\\MailSend_anhang.exe", params.c_str(), NULL, SW_HIDE) <= 32 )
return false;
return true;
}
I call it in the main method like this:
sendMail("-f:d.nitschmann#example.com -t:person2#example.com -s:Subject -b:Body " + test);
I think the problem is with your terminal; can you try run your test code in a different terminal ? one with known good UTF-8 support ?
Output with terminal in UTF-8 mode:
$ ./a.out
Success
Schrüder
Output with terminal in ISO-8859-15 mode:
$ ./a.out
Success
SchrÃŒder
Also - please try and follow http://sscce.org/ - for posterity sake here is your code with everything needed to compile (17676169.cpp):
#include <tinyxml2.h>
#include <string>
#include <iostream>
using namespace std;
using namespace tinyxml2;
tinyxml2::XMLDocument doc;
bool open(string path) {
if(doc.LoadFile(path.c_str()) == XML_SUCCESS)
return true;
return false;
}
int main() {
if(open("Test.xml"))
cout << "Success" << endl;
XMLNode * node = doc.RootElement();
string test = node->FirstChildElement()->GetText();
cout << test << endl;
return 0;
}
compiled with:
g++ -o 17676169 17676169.cpp -ltinyxml2
and uuencoded Test.xml - to ensure exact same data is used
begin 660 Test.xml
M/#]X;6P#=F5R<VEO;CTB,2XP(B!E;F-O9&EN9STB551&+3#B/SX*/&UY6$U,
M/#H#("`#/&UY.E185%]55$8X5&5S=#Y38VARP[QD97(\+VUY.E185%]55$8X
/5&5S=#X*/"]M>5A-3#X*
`
end
Edit 1:
If you want to confirm this theory - run this in eclipse:
#include <iostream>
#include <string>
#include <fstream>
int main()
{
std::ifstream ifs("Test.xml");
std::string xml_data((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
std::cout << xml_data;
}
Output with terminal in UTF-8 mode:
$ ./17676169.cat
<?xml version="1.0" encoding="UTF-8"?>
<myXML>
<my:TXT_UTF8Test>Schrüder</my:TXT_UTF8Test>
</myXML>
Output with terminal in ISO-8859-15 mode:
$ ./17676169.cat
<?xml version="1.0" encoding="UTF-8"?>
<myXML>
<my:TXT_UTF8Test>SchrÃŒder</my:TXT_UTF8Test>
</myXML>