How to Skip Parsing of Token in Rapidjson - c++

I have to Parse only certain Tokens in Data Structure using RapidJson.And skip other tokens to save time.
For eg. How to parse only "t" token without parsing other tokens
{
"hello": "world",
"t": true ,
"f": false,
"n": null,
}
I am using Iterative Parsing ,How do I parse only a certain token 'Key' .I have tried checking the 'Key' value to my required token and then retuening from code but program stopped executing.
struct MyHandler : public BaseReaderHandler<UTF8<>, MyHandler> {
bool Null() { cout << "Null()" << endl; return true; }
bool Bool(bool b) { cout << "Bool(" << boolalpha << b << ")" << endl; return true; }
bool Int(int i) { cout << "Int(" << i << ")" << endl; return true; }
bool Uint(unsigned u) { cout << "Uint(" << u << ")" << endl; return true; }
bool Int64(int64_t i) { cout << "Int64(" << i << ")" << endl; return true; }
bool Uint64(uint64_t u) { cout << "Uint64(" << u << ")" << endl; return true; }
bool Double(double d) { cout << "Double(" << d << ")" << endl; return true; }
bool String(const char* str, SizeType length, bool copy) {
cout << "String(" << str << ", " << length << ", " << boolalpha << copy << ")" << endl;
return true;
}
bool StartObject() { cout << "StartObject()" << endl; return true; }
bool Key(const char* str, SizeType length, bool copy) {
cout << "Key(" << str << ", " << length << ", " << boolalpha << copy << ")" << endl;
return true;
}
bool EndObject(SizeType memberCount) { cout << "EndObject(" << memberCount << ")" << endl;
return true; }
bool StartArray() { cout << "StartArray()" << endl; return true; }
bool EndArray(SizeType elementCount) { cout << "EndArray(" << elementCount << ")" << endl;
return true; }
};
//char* readBuffer is my json data in char array
MyHandler handler;
Reader reader;
StringStream ss(readBuffer);
reader.IterativeParseInit();
while (!reader.IterativeParseComplete()) {
reader.IterativeParseNext<kParseDefaultFlags>(ss, handler);
}
Thank You

You must maintain a state in your Handler set / unset depending if you have encountered the key you want to pass.
It is not straightforward because you must take into account that you can encounter the same key at various (nested) level.
If really you want to continue in this direction you can have a look in rapidjson example here https://github.com/Tencent/rapidjson/tree/master/example/filterkey
This make the opposite of your need, parsing everything except the given key. That should give you a good starting point.
Another solution is to use DOM parsing and "clean" after parsing the unwanted keys, which is much more easier. Off course it will not have the same performance but at least you will free memory associated with token you do not need.
auto itr = myDoc.MemberBegin();
while (itr != myDoc.MemberEnd())
{
if (itr->name == "keyIWantToKeep")
itr++;
else
itr = myDoc.EraseMember(itr);
}

Related

compilation error due to changing function's output data type

Forgive me if this is an obvious fix as I am very much a novice when it comes to C++.
For my assignment, we were given some starter code that simulates a command-line crypto trading platform. Originally, you would be prompted to type in commands 1 to 6 to do things like print exchange stats, make an offer, print the wallet and such. For my assignment, I've been asked to create an advisor bot that takes in string commands such as 'help' and processes this to return the appropriate output.
Naturally, since there was already a system in place to do this with integers as inputs, I tried to tweak the functions (I didn't do a lot yet) so they take string commands instead and output accordingly.
Before anything else, I would like to know why the function getUserOption and input is underlined red in the while loop of the init function, but in the actual function there are no errors:
This is the contents of the header file
#pragma once
#include <vector>
#include "OrderBookEntry.h"
#include "OrderBook.h"
#include "Wallet.h"
#include <string>
using namespace std;
class MerkelMain
{
public:
MerkelMain();
/** Call this to start the sim */
void init();
private:
void advisorBot();
void printHelp();
void printMarketStats();
void enterAsk();
void enterBid();
void printWallet();
void gotoNextTimeframe();
std::string getUserOption();
void processUserOption(string userOption);
void printCurrentTime();
std::string currentTime;
// OrderBook orderBook{"20200317.csv"};
OrderBook orderBook{"20200601.csv"};
Wallet wallet;
};
This is the cpp file
#include "MerkelMain.h"
#include <iostream>
#include <vector>
#include "OrderBookEntry.h"
#include "CSVReader.h"
#include <string>
using namespace std;
MerkelMain::MerkelMain()
{
}
void MerkelMain::init()
{
int input;
currentTime = orderBook.getEarliestTime();
wallet.insertCurrency("BTC", 10);
while(true)
{
advisorBot();
input = getUserOption();
processUserOption(input);
}
}
void MerkelMain::advisorBot()
{
std::cout << "Please enter a command, or help for a list of commands" << std::endl;
std::cout << "============== " << std::endl;
std::cout << "Current time is: " << currentTime << std::endl;
}
/*void MerkelMain::printMenu()
{
// 1 print help
std::cout << "1: Print help " << std::endl;
// 2 print exchange stats
std::cout << "2: Print exchange stats" << std::endl;
// 3 make an offer
std::cout << "3: Make an offer " << std::endl;
// 4 make a bid
std::cout << "4: Make a bid " << std::endl;
// 5 print wallet
std::cout << "5: Print wallet " << std::endl;
// 6 continue
std::cout << "6: Continue " << std::endl;
std::cout << "============== " << std::endl;
std::cout << "Current time is: " << currentTime << std::endl;
}*/
void MerkelMain::printHelp()
{
std::cout << " The available commands are help, help cmd, prod, min, max, avg, predict, time, step " << std::endl;
}
void MerkelMain::printMarketStats()
{
for (std::string const& p : orderBook.getKnownProducts())
{
std::cout << "Product: " << p << std::endl;
std::vector<OrderBookEntry> entries = orderBook.getOrders(OrderBookType::ask,
p, currentTime);
std::cout << "Asks seen: " << entries.size() << std::endl;
std::cout << "Max ask: " << OrderBook::getHighPrice(entries) << std::endl;
std::cout << "Min ask: " << OrderBook::getLowPrice(entries) << std::endl;
}
}
void MerkelMain::enterAsk()
{
std::cout << "Make an ask - enter the amount: product,price, amount, eg ETH/BTC,200,0.5" << std::endl;
std::string input;
std::getline(std::cin, input);
std::vector<std::string> tokens = CSVReader::tokenise(input, ',');
if (tokens.size() != 3)
{
std::cout << "MerkelMain::enterAsk Bad input! " << input << std::endl;
}
else {
try {
OrderBookEntry obe = CSVReader::stringsToOBE(
tokens[1],
tokens[2],
currentTime,
tokens[0],
OrderBookType::ask
);
obe.username = "simuser";
if (wallet.canFulfillOrder(obe))
{
std::cout << "Wallet looks good. " << std::endl;
orderBook.insertOrder(obe);
}
else {
std::cout << "Wallet has insufficient funds . " << std::endl;
}
}catch (const std::exception& e)
{
std::cout << " MerkelMain::enterAsk Bad input " << std::endl;
}
}
}
void MerkelMain::enterBid()
{
std::cout << "Make an bid - enter the amount: product,price, amount, eg ETH/BTC,200,0.5" << std::endl;
std::string input;
std::getline(std::cin, input);
std::vector<std::string> tokens = CSVReader::tokenise(input, ',');
if (tokens.size() != 3)
{
std::cout << "MerkelMain::enterBid Bad input! " << input << std::endl;
}
else {
try {
OrderBookEntry obe = CSVReader::stringsToOBE(
tokens[1],
tokens[2],
currentTime,
tokens[0],
OrderBookType::bid
);
obe.username = "simuser";
if (wallet.canFulfillOrder(obe))
{
std::cout << "Wallet looks good. " << std::endl;
orderBook.insertOrder(obe);
}
else {
std::cout << "Wallet has insufficient funds . " << std::endl;
}
}catch (const std::exception& e)
{
std::cout << " MerkelMain::enterBid Bad input " << std::endl;
}
}
}
void MerkelMain::printWallet()
{
std::cout << wallet.toString() << std::endl;
}
void MerkelMain::gotoNextTimeframe()
{
std::cout << "Going to next time frame. " << std::endl;
for (std::string p : orderBook.getKnownProducts())
{
std::cout << "matching " << p << std::endl;
std::vector<OrderBookEntry> sales = orderBook.matchAsksToBids(p, currentTime);
std::cout << "Sales: " << sales.size() << std::endl;
for (OrderBookEntry& sale : sales)
{
std::cout << "Sale price: " << sale.price << " amount " << sale.amount << std::endl;
if (sale.username == "simuser")
{
// update the wallet
wallet.processSale(sale);
}
}
}
currentTime = orderBook.getNextTime(currentTime);
}
std::string MerkelMain::getUserOption()
{
std::string userOption = "";
std::string line;
//std::cout << "Type in 1-6" << std::endl;
std::getline(std::cin, line);
try{
userOption = std::stoi(line);
}catch(const std::exception& e)
{
//
}
std::cout << "You chose: " << userOption << std::endl;
return userOption;
}
void printCurrentTime()
{
std::cout << "Current time is: " << currentTime << std::endl;
}
void MerkelMain::processUserOption(string userOption)
{
if (userOption == "help")
{
printHelp();
}
if (userOption == "help cmd")
{
printMarketStats();
}
if (userOption == "prod")
{
enterAsk();
}
if (userOption == "min")
{
enterBid();
}
if (userOption == "max")
{
printWallet();
}
if (userOption == "avg")
{
gotoNextTimeframe();
}
if (userOption == "predict")
{
enterAsk();
}
if (userOption == "time")
{
enterBid();
}
if (userOption == "step")
{
gotoNextTimeframe();
}
}
Your getUserOption() function returns a std::string. This means when you wrote:
input = getUserOption();
In the above statement the right hand side is of type std::string. On the other hand, the left hand side is of type int. So there is mismatch in the type of left hand side and right hand side expressions. Hence the error.
You can solve this by changing the type of variable input to std::string. So replace int input; by:
std::string input; //type changed to std::string

Sorting Vector(Bubble sort) c++

I have class Date, functions bubbleSort, isAfter and printVector. So my task is: Use the function bubbleSort to sort vector type objects Date(using function isAfter which compares dates). I've done something but it doesn't works, so can anyone help me with this?
Function bubble sort(doesn't works with "Date", works fine with integers ,strings...).
Here is my code:
//isAfter
template<>
bool isAfter(const Date &first, const Date &second) {
if (first.getYear() == second.getYear()) {
if (first.getMonth() == second.getMonth()) {
if (first.getDay() == second.getDay()) {
cout << first.toString() << " is equal to " << second.toString() << endl;
return false;
} else if (first.getDay() > second.getDay()) {
cout << " " << first.toString() << " is after " << " " << second.toString() << endl;
return true;
} else if (first.getDay() < second.getDay()) {
cout << " " << second.toString() << " is after " << " " << first.toString() << endl;
return true;
}
} else if (first.getMonth() > second.getMonth()) {
cout << " " << first.toString() << " is after " << " " << second.toString() << endl;
return true;
} else if (first.getMonth() < second.getMonth()) {
cout << " " << second.toString() << " is after " << " " << first.toString() << endl;
return true;
}
} else if (first.getYear() > second.getYear()) {
cout << " " << first.toString() << " is after " << " " << second.toString() << endl;
return true;
} else if (first.getYear() < second.getYear()) {
cout << " " << second.toString() << " is after " << " " << first.toString() << endl;
return true;
}
return false;
}
//bubbleSort
template<typename T>
void bubbleSort(vector<T> &vec) {
bool swapp= true;
while (swapp) {
swapp= false;
for (unsigned int i = 0; i < vec.size()- 1; i++) {
if (vec[i] > vec[i + 1]) {
swap(vec[i], vec[i + 1]);
swapp = true;
}
}
}
}
so how can i add isAfter in bubbleSort to work fine with "Date" objects?
If this is always the sort order for dates and you control that type, you could implement the comparison operators operator<, operator>, operator<=, operator>=, operator== and operator!= for that type.
Otherwise, the conventional approach is to modify your sorting algorithm to accept a custom comparator (by convention, having the interface of operator<, which requires you to flip your comparison) from its callers, something like:
template <typename T, typename Compare>
void bubbleSort(vector<T> &vec, Compare compare) {
// as you currently have, but using compare(a, b) instead of a < b
}
template <typename T>
void bubbleSort(vector<T> &vec) {
bubbleSort(vec, std::less<>());
}
Then callers can use isAfter like this:
bubbleSort(dates, [](const Date& a, const Date& b) { return isAfter(b, a); });

Having trouble getting my overloaded insertion operator to work

This is my main function
int main()
{
const string filename = "ass10data.txt"; // use your filename here
ifstream fin(filename.c_str());
if (!fin)
{
cerr << "Unable to open " << filename << endl;
exit(1);
}
string buffer;
Quadrilateral* ptrQuad;
while (getline(fin,buffer))
{
// Process only valid input
if (buffer.size() > 1)
{
ptrQuad = createQuadrilateralFromString(buffer);
cout << *ptrQuad << endl;
delete ptrQuad;
}
}
fin.close();
}
This is the overloaded insertion operator
ostream& operator<<(ostream&out, Quadrilateral *pointerQuad)
{
if (pointerQuad->getType() == "rectangle")
{
out << "Rectangle: sides " << pointerQuad->getFirst() << " and " << pointerQuad->getSecond() << " area=" << pointerQuad->area();
out << " perimeter=" << pointerQuad->perimeter();
return out;
}
else if(pointerQuad->getType() == "square")
{
out << "Square: side "<< pointerQuad->getFirst() << " area="<< pointerQuad->area();
out << " perimeter=" << pointerQuad->perimeter();
return out;
}
else if(pointerQuad->getType() == "parallelogram")
{
out << "Parallelogram: sides " << pointerQuad->getFirst() << " and " << pointerQuad->getSecond() << " area=" << pointerQuad->area();
out << " perimeter=" << pointerQuad->perimeter();
return out;
}
else if(pointerQuad->getType() == "rhombus")
{
out << "Rhombus: side "<< pointerQuad->getFirst() << " area="<< pointerQuad->area();
out << " perimeter=" << pointerQuad->perimeter();
return out;
}
else
return out;
}
I'm getting an error message saying "no match for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream}' and 'Quadrilateral')" and I can't figure out why.
The insertion operator should take a const reference to the Quadrilateral, not a pointer to it:
ostream& operator<<(ostream&out, Quadrilateral const &pointerQuad)
Of course, that means your function should use the value syntax, not the pointer one too.
if (pointerQuad.getType() == "rectangle")
{
out << "Rectangle: sides " << pointerQuad.getFirst() << " and " << pointerQuad.getSecond() << " area=" << pointerQuad.area();
out << " perimeter=" << pointerQuad.perimeter();
return out;
}
[...]

Using regex for input validation

I know the following isn't the most efficient implementation (I could, after all, run regex_match() right in main() ) but it should still work, at least from my limited understanding.
I'm trying to use in C++11 to validate some input for dicerolls. I used expresso to build the regular expressions, and it validates it within expresso just fine. Why would it fail within this code?
#include <iostream>
#include <string>
#include <regex>
bool regexValidate (string expr, string teststring)
{
regex ex(expr);
if (regex_match(teststring,ex)) {
return true;
cout << "true";
} else if (regex_match (teststring,regex("^\s*\d*d\d*\s*$"))) {
return true;
cout << "true";
}
return false;
}
int main()
{
char choice; // menu option selected by user
bool isExit = false; // Is the user ready to exit?
// test code
string diceexpr = "^\s*\d{1,}d\d{1,}\s*$";
string teststr = "10d10";
string teststr1 = "1d10";
string teststr2 = " 10d10 ";
cout << teststr << " is ";
if (regexValidate(diceexpr,teststr)) {
cout << " valid!" << endl;
} else {
cout << " invalid!" << endl;
}
cout << teststr1 << " is ";
if (regexValidate(diceexpr,teststr1)) {
cout << " valid!" << endl;
} else {
cout << " invalid!" << endl;
}
cout << teststr2 << " is ";
if (regexValidate(diceexpr,teststr2)) {
cout << " valid!" << endl;
} else {
cout << " invalid!" << endl;
}
return 0;
}
Sample output:
10d10 is invalid!
1d10 is invalid!
10d10 is invalid!
RUN SUCCESSFUL (total time: 291ms)
UPDATE
Corrected my code and changed it to use the boost library for regular expressions.
#include <iostream>
#include <string>
#include <boost/regex.hpp>
using namespace std;
bool regexValidate (string expr, string teststring)
{
boost::regex ex(expr);
if ( boost::regex_match (teststring,ex) ) {
cout << "true";
return true;
//} else if (regex_match (teststring,regex("^\s*\d*d\d*\s*$"))) {
// cout << "true";
// return true;
}
return false;
}
int main()
{
string diceexpr = "^\\s*\\d{1,}d\\d{1,}\\s*$";
string teststr = "10d10";
string teststr1 = "1d10";
string teststr2 = " 10d10 ";
cout << teststr << " is ";
if (regexValidate(diceexpr,teststr)) {
cout << " valid!" << endl;
} else {
cout << " invalid!" << endl;
}
cout << teststr1 << " is ";
if (regexValidate(diceexpr,teststr1)) {
cout << " valid!" << endl;
} else {
cout << " invalid!" << endl;
}
cout << teststr2 << " is ";
if (regexValidate(diceexpr,teststr2)) {
cout << " valid!" << endl;
} else {
cout << " invalid!" << endl;
}
return 0;
}
Given the following output:
terminate called after throwing an instance of 'std::regex_error'
what(): regex_error
RUN FAILED (exit value 1, total time: 1s)
string diceexpr = "^\s*\d{1,}d\d{1,}\s*$";
This doesn't do what you think it does. In a string literal, "\s" is the same as "s" (you should be seeing compiler warnings about unrecognized escape sequences), while "\\s" represents two characters, backslash and 's'.
Double up all backslashes, or else use a raw string literal for your regular expression, as in
string diceexpr = R"(^\s*\d{1,}d\d{1,}\s*$)";

Can not authorize through Evernote Api

I want to create a little client for Evernote.
I got the consumer key and secret from the site and wrote this code:
struct user_data {
std::string login;
std::string pass;
};
struct evernote_data {
user_data user;
std::string consumer_key;
std::string consumer_secret;
};
struct service_data
{
std::string host;
std::string path;
int port;
};
void connect(const evernote_data& account, const service_data& service)
{
try
{
boost::shared_ptr<TSSLSocketFactory> sslSocketFactory(new TSSLSocketFactory());
boost::shared_ptr<TSSLSocket> sslSocket=sslSocketFactory->createSocket(service.host, service.port);
boost::shared_ptr<TBufferedTransport> bufferedTransport(new TBufferedTransport(sslSocket));
boost::shared_ptr<TTransport> http_client(new THttpClient(bufferedTransport, service.host, service.path));
http_client->open();
boost::shared_ptr<TBinaryProtocol> user_store_protocol(new TBinaryProtocol(http_client));
evernote::edam::UserStoreClient user_store(user_store_protocol, user_store_protocol);
evernote::edam::AuthenticationResult auth_result;
user_store.authenticate(auth_result, account.user.login, account.user.pass, account.consumer_key, account.consumer_secret);
cout << "Some info: " ;
cout << auth_result.user.username << endl << auth_result.user.name << endl << auth_result.user.email << endl;
}
catch(evernote::edam::EDAMUserException& error)
{
cout << "catch EDAMUserException" << endl;
cout << "ErrorCode: " << error.errorCode << endl;
cout << "What: " << error.what() << endl;
cout << "Parameter: " << error.parameter << endl;
}
catch(::apache::thrift::TException& error)
{
cout << "catch thrift::TException " << endl;
cout << "What: " << error.what() << endl;
}
catch(...)
{
cout << "boom !!!" << endl;
}
}
int main()
{
const user_data user = { "**Login**", "**password**"};
const evernote_data account = { user, "***Key***", "**Secret**" };
const service_data service = {"sandbox.evernote.com", "/edam/user", 443 };
connect(account, service);
std::cout << "Exit" << std::endl;
cin.get();
return 0;
}
Program output:
Catch EDAMUserException
ErrorCode: 8
What: Default TException.
Parameter: consumerKey
And always catch error about wrong consumer key. What am I doing wrong?
Third party developers can't use UserStore#authenticate since last November.
http://dev.evernote.com/documentation/reference/UserStore.html#Fn_UserStore_authenticate
Please use OAuth instead.
http://dev.evernote.com/start/core/authentication.php