C++ rapidjson "‘rapidjson::Document’ has no member named ‘GetParseErrorCode'" - rapidjson

I am trying to compile this program:
`
#include "rapidjson/document.h"
#include "rapidjson/error/en.h"
#include <stdio.h>
#include <iostream>
int main() {
const char* json =
"{"
"\"hello\": \"world\","
"\"t\": \"world\""
"}";
const char* msgJson =
"{"
"\"t\": \"MESSAGE_CREATE\","
"\"s\": 59,"
"\"op\": 0,"
"\"d\":{"
"\"tts\": false,"
"\"timestamp\": \"2016-04-29T02:40:47.490000+00:00\","
"\"nonce\": \"175436196699176960\","
"\"mentions\": [ [Object] ],"
"\"mention_everyone\": false,"
"\"id\": \"175436191456428032\","
"\"embeds\": [],"
"\"edited_timestamp\": null,"
"\"content\": \"<#174463430873317376> count stuff\","
"\"channel_id\": \"81402706320699392\","
"\"author\": {"
"\"username\": \"#C2185B #AD1457 #880E4F\","
"\"id\": \"125422419736395777\","
"\"discriminator\": \"0672\","
"\"avatar\": \"57ca1bf97372796648a2aac4b20614af\""
"},"
"\"attachments\": []"
"}"
"}";
rapidjson::Document document;
document.Parse(json);
assert(document.IsObject());
assert(document.HasMember("hello"));
assert(document["hello"].IsString());
printf("hello = %s\n", document["hello"].GetString());
assert(document.HasMember("t"));
assert(document["t"].IsString());
printf("t = %s\n", document["t"].GetString());
rapidjson::Document message;
rapidjson::ParseResult result = message.Parse(msgJson);
//std::cout << rapidjson::ParseErrorCode << std::endl;
printf("%u - %s\n", (unsigned)message.GetErrorOffset(), rapidjson::GetParseError_En(message.GetParseErrorCode()));
assert(message.IsObject());
assert(message.HasMember("t"));
printf("%s\n", message["t"].GetString());
return 0;
}
`
but keep getting this error:
`
json_example.cpp: In function ‘int main()’:
json_example.cpp:53:97: error: ‘rapidjson::Document’ has no member named ‘GetParseErrorCode’
printf("%u - %s\n", (unsigned)message.GetErrorOffset(), rapidjson::GetParseError_En(message.GetParseErrorCode()));
`
How would I solve this problem? Because according to the rapidjson docs this is the correct way to do it. Or does anyone know of a better way to parse JSON with C++?

GetParseErrorCode should be GetParseError - this was a mistake in the docs. Also, in the JSON, [ [ Object ] ] isn't a correct value.

Related

How to use CGAL::read_ply_points() to read binary ply files?

A new user of CGAL here.
I am currently trying out the example "registration_with_OpenGR.cpp"
https://cgal.geometryfactory.com/CGAL/doc/master/Point_set_processing_3/Point_set_processing_3_2registration_with_OpenGR_8cpp-example.html
It seems that the function CGAL::read_ply_points() that is used to read ply files does not work on binary format, but it works when a ASCII ply file is given. Is there any extra flag that I need to set when reading binary ply files?
here is my current code for reading ply files.
#include <CGAL/property_map.h>
#include <fstream>
#include <iostream>
#include <utility>
#include <vector>
typedef CGAL::Simple_cartesian<double> K;
typedef K::Point_3 Point_3;
typedef K::Vector_3 Vector_3;
typedef std::pair<Point_3, Vector_3> Pwn;
typedef CGAL::First_of_pair_property_map<Pwn> Point_map;
typedef CGAL::Second_of_pair_property_map<Pwn> Normal_map;
namespace params = CGAL::parameters;
int main(int argc, const char** argv) {
const char* fname1 = "data/reference.ply";
const char* fname2 = "data/1.ply";
std::vector<Pwn> pwns1, pwns2;
std::ifstream input(fname1);
if (!input ||
!CGAL::read_ply_points(input, std::back_inserter(pwns1),
CGAL::parameters::point_map(CGAL::First_of_pair_property_map<Pwn>()).
normal_map(Normal_map())))
{
std::cerr << "Error: cannot read file " << fname1 << std::endl;
return EXIT_FAILURE;
}
input.close();
input.open(fname2);
if (!input ||
!CGAL::read_ply_points(input, std::back_inserter(pwns2),
CGAL::parameters::point_map(Point_map()).
normal_map(Normal_map())))
{
std::cerr << "Error: cannot read file " << fname2 << std::endl;
return EXIT_FAILURE;
}
input.close();
std::cerr << "SUCCESS" << std::endl;
return EXIT_SUCCESS;
}
You need to give std::ios_base::binary to your stream constructor:
std::ifstream input(fname1,std::ios_base::binary);

How to print eight words to a line using vector<string>?

I was trying to make a program write 8 words to a line after a user enter their sentence.Its only printing words that have been typed in and i don't have a clue how to make it type 8 words to a line.
#include <iostream>
#include <vector>
#include <string>
#include <cctype>
using namespace std;
vector<string> sentence;
string sente = "";
void print(string, string);
template<typename T>
void print(vector<T>& v, string)
{
cout << "Enter your sentence " << endl;
getline(cin, sente);
sentence.push_back(sente);
for (auto const elem: sentence)
{
cout << elem;
}
}
int main()
{
print(sentence,sente);
}
Using global variables is generally not a good practice.
Also you don't need a extra vector for your use case.
Take a look at the following code, where you can smartly make use of istringstream for your use case:
#include <iostream>
#include <string>
#include <sstream>
void print()
{
std::string sente;
std::cout << "Enter your sentence " << std::endl;
getline(std::cin, sente);
// Used to split string around spaces.
std::istringstream ss(sente);
int wordCountPerLine = 0;
int requiredWordsPerLine = 8;
// Traverse through all words
do {
// Read a word
std::string word;
ss >> word;
// Print the read word
std::cout << word << " ";
wordCountPerLine++;
if(wordCountPerLine % requiredWordsPerLine == 0){
std::cout<<std::endl;
wordCountPerLine = 0;
}
// While there is more to read
} while (ss);
}
int main()
{
print();
}
Feel free to ask any doubts.

C++ portability from Windows to Linux

I have been successfully using the following code in C++ on Windows (via CodeBlocks) and have recently attempted to use the same code on Linux (Ubuntu 18.04) also via CodeBlocks. The code appears to compile fine but fails on execution.
The purpose of the code is to import a comma delimited text file of numbers into an array.
In both Windows and Linux I am using the GNU GCC Compiler.
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <cmath>
#include <iomanip>
#include <ctime>
#include <cstdio>
#include <stdlib.h>
using namespace std;
typedef vector <double> record_t;
typedef vector <record_t> data_t;
istream& operator >> ( istream& ins, record_t& record)
{
record.clear();
string line;
getline( ins, line );
stringstream ss( line );
string field;
while (getline( ss, field, ',' ))
{
stringstream fs( field );
double f = 0.0;
fs >> f;
record.push_back( f );
}
return ins;
}
//-----------------------------------------------------------------------------
istream& operator >> ( istream& ins, data_t& data )
{
data.clear();
record_t record;
while (ins >> record)
{
data.push_back( record );
}
return ins;
}
//-----------------------------------------------------------------------------
int main()
{
data_t data;
ifstream infile( "Import File.txt" );
infile >> data;
if (!infile.eof())
{
cout << "Unsuccessful Import!\n";
return 1;
}
infile.close();
cout << "Your file contains " << data.size()-1 << " records.\n";
return 0;
}
I've checked that the necessary header files exist on Linux and that appears to be the case.
If I comment out the EOF check the console returns the message that
Process returned 49 (0x31)
A snippet of the import file which fails under Linux is:
1138,1139,1137.25,1138.5
1138.25,1138.75,1138.25,1138.5
1138.75,1139,1138.5,1138.75
1138.75,1138.75,1138.25,1138.25
1138.25,1138.25,1137.5,1137.5
1137.5,1138.75,1137.5,1138.5
1138.75,1143.75,1138.75,1143
1143.25,1145.75,1143.25,1144.5
1144.5,1144.75,1143,1143.25
1143.5,1144.5,1143.25,1144.25
Grateful for any help in finding a solution.
That return 4321; in main reports an unsuccessful return code to the OS. Only 0 return code (aka EXIT_SUCCESS) is considered successful.
Change it to return 0 or completely remove that return statement (in C++ main has implicit return 0).

How to use boost.spirit.qi parse string value to attrubute with attribute has default value

I have a question for boost.spirit.qi string parser. When I want parse string value to std::string attribute, like bellow:
#include <boost/spirit/include/support_utree.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/assert.hpp>
#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>
template <typename P, typename T>
void test_phrase_parser_attr(
char const* input, P const& p, T& attr, bool full_match = true)
{
using boost::spirit::qi::phrase_parse;
using boost::spirit::qi::ascii::space;
char const* f(input);
char const* l(f + strlen(f));
if (phrase_parse(f, l, p, space, attr) && (!full_match || (f == l)))
std::cout << "ok" << std::endl;
else
std::cout << "fail" << std::endl;
}
int main()
{
std::string str("abc");
test_phrase_parser_attr("cba", string("cba"), str);
std::cout << str << std::endl;
return 0;
}
The output:abccba
But I want the program output "cba", How can I do?
Note that your str was initialized with "abc". Parser does not clear the string, just appends its output.
Pass in an empty string and you will get back what you want.

Reversing words of a string inplace using STL

This question has been done to death in SO:. Here is my version using STL functions of the tradition algorithm of reversing the string and then reversing the words. is there a more elegant soln without using loops?
std::string something;
std::getline(std::cin, something);
std::reverse(something.begin(), something.end());
for (size_t i = 0, size_t nextPos = something.find_first_of(' ', i);
nextPos != std::string::npos; i = nextPos + 1,
nextPos = something.find_first_of(' ', i)) {
std::string::iterator startIter = something.begin() + i;
std::string::iterator endIter = something.begin() + nextPos;
std::reverse(startIter, endIter);
}
Assume the input is perfect no space before and after sentence and exactly single space between words. Is there an stl solution that requires no loop?
Best,
Subramanian
Here's a loop-free way using iterators and a closure:
#include <iterator>
#include <algorithm>
#include <sstream>
#include <string>
std::istringstream iss(something);
std::string sentence;
std::for_each(std::istream_iterator<std::string>(iss),
std::istream_iterator<std::string>(),
[&sentence](std::string const & s) { sentence.insert(0, s + ' '); }
);
Update: Here is an in-place algorithm with one single loop:
#include <string>
#include <algorithm>
void reverse(std::string & s)
{
for (std::size_t pos, done = 0;
(pos = s.find(' ')) != s.npos && ++pos + done <= s.size();
done += pos)
{
std::rotate(s.begin(), s.begin() + pos, s.end() - done);
}
}
Example:
#include <iostream>
int main()
{
for (std::string line; std::getline(std::cin, line); )
{
reverse(line);
std::cout << '"' << line << '"' << std::endl;
}
}
Test run:
$ echo "hello world how are you " | ./prog
"you are how world hello "

Resources