here is the json I want to parse:
{"jsonrpc":"2.0","method":"subscription","params":{"channel":"book.BTC-PERPETUAL.raw","data":{"type":"change","timestamp":1635513739435,"prev_change_id":6807100702,"instrument_name":"BTC-PERPETUAL","change_id":6807100703,"bids":[["new",60772.0,50.0], "demo"],"asks":[]}}}
and here is my code to get the values from a child:
boost::property_tree::ptree pt;
boost::property_tree::read_json(ss, pt);
std::cout << "\njsonrpc: " << pt.get<std::string>("jsonrpc") << std::endl;
std::cout << "\nmethod: " << pt.get<std::string>("method") << std::endl;
std::cout << "\nparams: " << pt.get<std::string>("params") << std::endl;
std::cout << "\nparams.channel: " << pt.get<std::string>("params.channel") << std::endl;
std::cout << "\nparams.data: " << pt.get<std::string>("params.data") << std::endl;
std::cout << "\nparams.data.timestamp: " << pt.get<std::string>("params.data.timestamp") << std::endl;
std::cout << "\nparams.data.instrument_name: " << pt.get<std::string>("params.data.instrument_name") << std::endl;
but when I tried to parse the array values like ("params.data.bids") it return nothing
I need help in parsing an array
You should use a JSON Library:
Live On Compiler Explorer
#include <boost/json.hpp>
#include <boost/json/src.hpp> // header-only for Compiler Explorer
#include <iostream>
namespace json = boost::json;
int main() {
auto req = json::parse(R"({
"jsonrpc": "2.0",
"method": "subscription",
"params": {
"channel": "book.BTC-PERPETUAL.raw",
"data": {
"type": "change",
"timestamp": 1635513739435,
"prev_change_id": 6807100702,
"instrument_name": "BTC-PERPETUAL",
"change_id": 6807100703,
"bids": [
["new", 60772.0, 50.0], "demo"],
"asks": []
}
}
})") .as_object();
auto& params = req["params"].as_object();
auto& data = params["data"].as_object();
std::cout << "jsonrpc: " << req["jsonrpc"].as_string() << "\n";
std::cout << "methdo: " << req["method"].as_string() << "\n";
std::cout << "params.channel: " << params["channel"].as_string() << "\n";
std::cout << "params.data: " << params["data"] << "\n";
std::cout << "params.data.timestamp: " << data["timestamp"] << "\n";
std::cout << "params.data.instrument_name: " << data["instrument_name"] << "\n";
}
Prints
jsonrpc: "2.0"
methdo: "subscription"
params.channel: "book.BTC-PERPETUAL.raw"
params.data: {"type":"change","timestamp":1635513739435,"prev_change_id":6807100702,"instrument_name":"BTC-PERPETUAL","change_id":6807100703,"bids":[["new",6.0772E4,5E1],"demo"],"asks":[]}
params.data.timestamp: 1635513739435
params.data.instrument_name: "BTC-PERPETUAL"
bid: ["new",6.0772E4,5E1]
bid: "demo"
Adding the asks/bids:
for (auto& bid : data["bids"].as_array()) {
std::cout << "bid: " << bid << "\n";
}
for (auto& ask : data["asks"].as_array()) {
std::cout << "ask: " << ask << "\n";
}
Prints
bid: ["new",6.0772E4,5E1]
bid: "demo"
Alternative / Bonus
You can also use value_to conversion to your own types:
struct request {
std::string jsonrpc, method;
struct params_t {
std::string channel;
struct data_t {
std::string type;
size_t timestamp, prev_change_id, change_id;
std::string instrument_name;
std::vector<json::value> bids, asks;
} data;
} params;
};
See it Live
Or flattened:
struct request {
using values = std::vector<json::value>;
std::string jsonrpc, method, channel, type, instrument_name;
size_t timestamp, prev_change_id, change_id;
values bids, asks;
friend request tag_invoke(json::value_to_tag<request>, json::value const& v)
{
auto& params = v.at("params");
auto& data = params.at("data");
return request{
value_to<std::string>(v.at("jsonrpc")),
value_to<std::string>(v.at("method")),
value_to<std::string>(params.at("channel")),
value_to<std::string>(data.at("type")),
value_to<std::string>(data.at("instrument_name")),
value_to<size_t>(data.at("timestamp")),
value_to<size_t>(data.at("prev_change_id")),
value_to<size_t>(data.at("change_id")),
value_to<values>(data.at("bids")),
value_to<values>(data.at("asks")),
};
}
};
See it Live As Well
#include <boost/json.hpp>
#include <boost/json/src.hpp> // header-only for Compiler Explorer
#include <iostream>
namespace json = boost::json;
struct request {
using values = std::vector<json::value>;
std::string jsonrpc, method, channel, type, instrument_name;
size_t timestamp, prev_change_id, change_id;
values bids, asks;
friend request tag_invoke(json::value_to_tag<request>, json::value const& v)
{
auto& params = v.at("params");
auto& data = params.at("data");
return request{
value_to<std::string>(v.at("jsonrpc")),
value_to<std::string>(v.at("method")),
value_to<std::string>(params.at("channel")),
value_to<std::string>(data.at("type")),
value_to<std::string>(data.at("instrument_name")),
value_to<size_t>(data.at("timestamp")),
value_to<size_t>(data.at("prev_change_id")),
value_to<size_t>(data.at("change_id")),
value_to<values>(data.at("bids")),
value_to<values>(data.at("asks")),
};
}
};
int main() {
auto req = value_to<request>(json::parse(R"({
"jsonrpc": "2.0",
"method": "subscription",
"params": {
"channel": "book.BTC-PERPETUAL.raw",
"data": {
"type": "change",
"timestamp": 1635513739435,
"prev_change_id": 6807100702,
"instrument_name": "BTC-PERPETUAL",
"change_id": 6807100703,
"bids": [
["new", 60772.0, 50.0], "demo"],
"asks": []
}
}
})"));
std::cout << "jsonrpc: " << req.jsonrpc << "\n";
std::cout << "methdo: " << req.method << "\n";
std::cout << "params.channel: " << req.channel << "\n";
std::cout << "data.timestamp: " << req.timestamp << "\n";
std::cout << "data.instrument_name: " << req.instrument_name << "\n";
for (auto& bid : req.bids) std::cout << "bid: " << bid << "\n";
for (auto& ask : req.asks) std::cout << "ask: " << ask << "\n";
}
Related
I am referring to sample code on Crypto++ wiki at CCM Mode. I have done few modifications for testing purposes and now it is throwing:
terminate called after throwing an instance of 'HashVerificationFilter::HashVerificationFailed'
what(): HashVerificationFilter: message hash or MAC not valid
Aborted (core dumped)
I have seen 'message hash or MAC not valid' exception after decryption. But I would like to pass byte array instead of string, so I think I have to use sizeof() operator instead of size(). The code is below.
When pass key and iv, sizeof function is giving their sizes as 8 instead 16 bytes.
Is the error because of AuthenticatedDecryptionFilter::DEFAULT_FLAGS?
Here is the code:
#include <iostream>
#include <cstdio>
//#include "libcryptoWrapperGCM.h"
using std::cout;
using std::endl;
using std::cerr;
#include <string>
#include <stdint.h>
using std::string;
#include "hex.h"
using CryptoPP::HexEncoder;
using CryptoPP::HexDecoder;
#include "osrng.h"
using CryptoPP::AutoSeededRandomPool;
#include "cryptlib.h"
using CryptoPP::BufferedTransformation;
using CryptoPP::AuthenticatedSymmetricCipher;
#include "filters.h"
using CryptoPP::Redirector;
using CryptoPP::StringSink;
using CryptoPP::StringSource;
using CryptoPP::AuthenticatedEncryptionFilter;
using CryptoPP::AuthenticatedDecryptionFilter;
#include "aes.h"
using CryptoPP::AES;
#include "gcm.h"
using CryptoPP::GCM;
#include "assert.h"
void GCM_Encode(byte key[], byte iv[], string pdata, string cipher, const int TAG_SIZE)
{
// Encrypted, with Tag
string encoded;
cout << "key size= " << sizeof(key) << endl;
cout << "IV size= " << sizeof(iv) << endl;
/*********************************\
\*********************************/
try
{
GCM< AES >::Encryption e;
e.SetKeyWithIV( key, sizeof(key), iv, sizeof(iv) );
StringSource ss1( pdata, true,
new AuthenticatedEncryptionFilter( e,
new StringSink( cipher ), false, TAG_SIZE
) // AuthenticatedEncryptionFilter
); // StringSource
cout << "Encoded value: " << cipher << endl;
}
catch( CryptoPP::Exception& e )
{
cerr << e.what() << endl;
exit(1);
}
}
/*********************************\
\*********************************/
void GCM_Decode(byte key[], byte iv[], string cipher, string rpdata, const int TAG_SIZE)
{
try
{
GCM< AES >::Decryption d;
d.SetKeyWithIV( key, sizeof(key), iv, sizeof(iv) );
AuthenticatedDecryptionFilter df( d,
new StringSink( rpdata ),
AuthenticatedDecryptionFilter::DEFAULT_FLAGS, TAG_SIZE
); // AuthenticatedDecryptionFilter
// The StringSource dtor will be called immediately
// after construction below. This will cause the
// destruction of objects it owns. To stop the
// behavior so we can get the decoding result from
// the DecryptionFilter, we must use a redirector
// or manually Put(...) into the filter without
// using a StringSource.
StringSource ss2( cipher, true,
new Redirector( df /*, PASS_EVERYTHING */ )
); // StringSource
// If the object does not throw, here's the only
// opportunity to check the data's integrity
if( true == df.GetLastResult() ) {
cout << "recovered text: " << rpdata << endl;
}
}
catch( CryptoPP::Exception& e )
{
cerr << e.what() << endl;
exit(1);
}
}
int main()
{
byte key[]= {0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f};
byte iv[] = {0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f};
string pdata = "Authenticated Encryption";
const int TAG_SIZE = 12;
string rpdata, cipher;
//void GCM_Encode(byte key[], byte iv[], string pdata, string cipher, const int TAG_SIZE)
GCM_Encode( key, iv, pdata, cipher, TAG_SIZE);
cout << "======INT MAIN======" << endl;
cout << "Encryption complete" << endl;
cout << "cipher= " << cipher << endl;
//void GCM_Decode(byte key[], byte iv[], string cipher, string rpdata, const int TAG_SIZE)
GCM_Decode( key, iv, cipher, rpdata, TAG_SIZE);
cout << "Decryption complete" << endl;
cout << "rpdata= " << rpdata << endl;
return 0;
}
GDB output is,
Encryption complete
cipher=
HashVerificationFilter: message hash or MAC not valid
[Inferior 1 (process 16632) exited with code 01]
Compilation command
g++ -g3 -O3 -fPIC GCM_Test2.cpp -o GCMTest3 -lcryptopp -pthread -lrt -lc
Include path added using,
export CPLUS_INCLUDE_PATH=/usr/local/include/cryptopp
No output on locate raise.c
Problem is that both functions GCM_Encode were interpreting wrong size of key and iv.
cout << "sizeof(key)= " << sizeof(key) << endl;
cout << "sizeof(iv)= " << sizeof(iv) << endl;
is 8 and not 16. So idea is to convert it to string and get its size using .size()
std::string key1( reinterpret_cast<char const*>(key), sizeof(key) )
std::string iv1( reinterpret_cast<char const*>(iv), sizeof(iv) )
But remember to provide original byte array to SetKeyWithIV function as it does not accept string as its argument.
e.SetKeyWithIV( key, key1.size(), iv, iv1.size() )
I have a JSON string, in which value is actually a string, but I need to access it like JSON array. {"data" : "[A,B,C]"}.
Is there any way to parse VALUE as Indexed array using RapidJSON so that I get a document like: {"0" : "A", "1" : "B", "2" : "C"}
RapidJSON Should be fully in compliance With RFC7159 / ECMA-404.
No there is no way, you need to do it manually.
For example using regex:
#include <iostream>
#include <iterator>
#include <string>
#include <regex>
static std::regex value_regex("[\\s]*([\\w\\s]+),?", std::regex::optimize);
std::string parse(const std::string& value) {
if (value.at(0) != '[' || value.at(value.size() - 1) != ']') {
throw std::invalid_argument("Error in Parse [must start with '[' and end with ']']: " + value);
}
std::string result("{");
std::sregex_iterator next(++value.begin(), --value.end(), value_regex, std::regex_constants::match_continuous);
std::sregex_iterator end;
size_t len = 0, cont = 0;
while (next != end) {
if (cont) {
result.append(", \"").append(std::to_string(cont)).append("\":\"").append(next->str(1)).append(1, '\"');
} else {
result.append(1, '\"').append(std::to_string(cont)).append("\":\"").append(next->str(1)).append(1, '\"');
}
len += next->length(0);
++next;
++cont;
}
if (len != value.size() - 2) {
throw std::invalid_argument("Error in Parse [" + std::to_string(len) + "]: " + value);
}
result.append(1, '}');
return result;
}
int main() {
// Tests
try {
std::string value("[A,B,C,D,E]");
std::cout << value << " -> " << parse(value) << std::endl;
} catch (const std::invalid_argument& err) {
std::cout << err.what() << std::endl;
}
try {
std::string value("[ A, B X, Z]");
std::cout << value << " -> " << parse(value) << std::endl;
} catch (const std::invalid_argument& err) {
std::cout << err.what() << std::endl;
}
try {
std::string value("[A,BaaayyX, Z]");
std::cout << value << " -> " << parse(value) << std::endl;
} catch (const std::invalid_argument& err) {
std::cout << err.what() << std::endl;
}
try {
std::string value("[A,B,C,]");
std::cout << value << " -> " << parse(value) << std::endl;
} catch (const std::invalid_argument& err) {
std::cout << err.what() << std::endl;
}
try {
std::string value("[]");
std::cout << value << " -> " << parse(value) << std::endl;
} catch (const std::invalid_argument& err) {
std::cout << err.what() << std::endl;
}
// Errors
try {
std::string value("A,B,C");
std::cout << value << " -> " << parse(value) << std::endl;
} catch (const std::invalid_argument& err) {
std::cout << err.what() << std::endl;
}
try {
std::string value("A,B,C]");
std::cout << value << " -> " << parse(value) << std::endl;
} catch (const std::invalid_argument& err) {
std::cout << err.what() << std::endl;
}
try {
std::string value("[A,B,C");
std::cout << value << " -> " << parse(value) << std::endl;
} catch (const std::invalid_argument& err) {
std::cout << err.what() << std::endl;
}
try {
std::string value("[,A,B,C]");
std::cout << value << " -> " << parse(value) << std::endl;
} catch (const std::invalid_argument& err) {
std::cout << err.what() << std::endl;
}
try {
std::string value("");
std::cout << value << " -> " << parse(value) << std::endl;
} catch (const std::exception& err) {
std::cout << err.what() << std::endl;
}
try {
std::string value("[");
std::cout << value << " -> " << parse(value) << std::endl;
} catch (const std::exception& err) {
std::cout << err.what() << std::endl;
}
try {
std::string value("]");
std::cout << value << " -> " << parse(value) << std::endl;
} catch (const std::exception& err) {
std::cout << err.what() << std::endl;
}
}
Output:
[A,B,C,D,E] -> {"0":"A", "1":"B", "2":"C", "3":"D", "4":"E"}
[ A, B X, Z] -> {"0":"A", "1":"B X", "2":"Z"}
[A,BaaayyX, Z] -> {"0":"A", "1":"BaaayyX", "2":"Z"}
[A,B,C,] -> {"0":"A", "1":"B", "2":"C"}
[] -> {}
A,B,C -> Error in Parse [must start with '[' and end with ']']: A,B,C
A,B,C] -> Error in Parse [must start with '[' and end with ']']: A,B,C]
[A,B,C -> Error in Parse [must start with '[' and end with ']']: [A,B,C
[,A,B,C] -> Error in Parse [0]: [,A,B,C]
-> basic_string
[ -> Error in Parse [must start with '[' and end with ']']: [
] -> Error in Parse [must start with '[' and end with ']']: ]
You can customize your regex to become more flexible or more strict.
I have noticed that whenever I use dark background images for tesseract I am getting a segmentation fault. I was trying to extract symbols using this code
#include <tesseract/baseapi.h>
#include <leptonica/allheaders.h>
#include <iostream>
#include <map>
#include <bits/stdc++.h>
using namespace std;
int main()
{
char *outText;
map<pair<char*,char*>,float> matrix;
set<char> allChars;
tesseract::TessBaseAPI *api = new tesseract::TessBaseAPI();
// Initialize tesseract-ocr with English, without specifying tessdata path
if (api->Init(NULL, "eng")) {
fprintf(stderr, "Could not initialize tesseract.\n");
exit(1);
}
int a[256][256];
for(int i=0;i<256;i++){
for(int j=0;j<256;j++){
a[i][j]=0;
}
}
// Open input image with leptonica library
string images[] = {List of images};
for (int ii=0;ii<7;ii++){
Pix *image = pixRead((const char*) images[ii].c_str());
cout << images[ii] << endl;
api->Init(NULL, "eng");
api->SetImage(image);
string valid_set = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890~`!##$%^&*()_-+=,./<>/:;'[]{}|";
api->SetVariable("tessedit_char_whitelist", valid_set.c_str());
api->SetVariable("save_blob_choices", "T");
//api->SetRectangle(37, 128,648, 523);
//api->SetRectangle(30, 86, 590, 100);
//api->SetRectangle(30,100,430,30);
api->Recognize(NULL);
tesseract::ResultIterator* ri = api->GetIterator();
tesseract::PageIteratorLevel level = tesseract::RIL_SYMBOL;
if(ri != 0) {
do {
const char* symbol = ri->GetUTF8Text(level);
//cout << symbol << endl;
if(ri!=0){
float conf = ri->Confidence(level);
}
//cout << "err" << endl;
if(symbol != 0) {
//printf("symbol %s, conf: %f", symbol, conf);
bool indent = false;
tesseract::ChoiceIterator ci(*ri);
do {
const char* choice = ci.GetUTF8Text();
if (indent) //printf("\t\t ");
// printf("\t- ");
//cout << symbol<<" Look up "<<choice << endl;
matrix[make_pair(strdup(symbol), strdup(choice))]=ci.Confidence();
//printf("%s conf: %f\n", choice, ci.Confidence());
indent = true;
} while(ci.Next());
}
//printf("---------------------------------------------\n");
delete[] symbol;
} while((ri->Next(level)));
}
int count = 0;
for(map<pair<char*,char*>,float>::iterator it = matrix.begin();it!=matrix.end();it++){
allChars.insert((strdup)(it->first.first)[0]);
allChars.insert((strdup)(it->first.second)[0]);
//cout<<it->first.first<<" "<<it->first.second<<endl;
//cout << (strdup)(it->first.first)[0]<<" "<<(strdup)(it->first.second)[0]<<endl;
a[(strdup)(it->first.first)[0]][(strdup)(it->first.second)[0]]+=it->second;
count++;
}
// cout << count << endl;
for(set<char>::iterator it = allChars.begin();it!=allChars.end();it++){
//cout << *it << endl;
}
for(int i=0;i<256;i++){
for(int j=0;j<256;j++){
if(a[i][j]!=0){
///cout << i << " " <<j<<endl;
//cout << a[i][j]<<endl;
}
//cout << a[i][j] << endl;
}
}
api->End();
pixDestroy(&image);
}
return 0;
}`
Specifically in the code where
float conf = ri->Confidence(level);
So what can be the solution to this problem? Should we train with more dark images?
Edit:
Sample Image
I'm writing a code for a basic adt text editor with a doubly linked list ( for HW ) and Ive run across the error C2244:'Editor::run_command ' :unable to match function to existing declaration. I orignalyy declared the function in my Editor class but i have to use Template in order to use some of the variables from a template class if someon could help me out i'd appreicate it a ton
// assignment 2-2.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <assert.h>
#include <string>
#include <windows.h>
#include <list>
using namespace std;
template <class Node_entry>
struct Node {
// data members
Node_entry entry;
Node<Node_entry> *next;
Node<Node_entry> *back;
// constructors
Node( );
~Node();
Node(Node_entry, Node<Node_entry> *link_back = NULL,
Node<Node_entry> *link_next = NULL);
};
template <class List_entry>
class List {
public:
// methods of the List ADT
List( );
int size( ) const;
bool full( ) const;
bool empty( ) const;
void clear( );
int count;
error_code traverse(void (*visit)(List_entry &));
error_code retrieve(int position, List_entry &x) const;
error_code remove(int position, List_entry &x);
error_code insert(int position, const List_entry &x);
protected:
// data members for a contiguous list implementation
List_entry entry[15];
mutable int current_position;
mutable Node<List_entry> *current;
void set_position(int position) const
{
if (current position <= position)
for ( ; current_position != position; current_position++)
current = current->next;
else
for ( ; current_position != position; current_position−−)
current = current->back;
}
};
template <class List_entry>
int List<List_entry>::size( ) const
{
return count;
};
template <class List_entry>
error_code List<List_entry>::insert(int position, const List_entry &x)
{
Node<List_entry> *new_node, *following, *preceding;
if (position < 0 || position > count) return range_error;
if (position == 0) {
if (count == 0) following = NULL;
else {
set_position(0);
following = current;
}
preceding = NULL;
}
else {
set_position(position − 1);
preceding = current;
following = preceding->next;
}
new_node = new Node<List_entry>(x, preceding, following);
if (new_node == NULL)
return overflow;
if (preceding != NULL)
preceding->next = new_node;
if(following != NULL) following->back = new_node;
current=new_node;
current_position=position;
count++;
return success;
};
class Editor: public List<string> {
public:
Editor(ifstream *file_in, ofstream *file_out);
bool get_command( );
void run_command( );
private:
ifstream *infile;
ofstream *outfile;
char user_command;
// auxiliary functions
error_code next_line( );
error_code previous_line( );
error_code goto_line( );
error_code insert_line( );
error_code substitute_line( );
error_code change_line( );
void write_file( );
void read_file( );
void find_string( );
};
int main(int argc, char *argv[ ])
{
if (argc != 3) {
cout << "Usage:\n\t edit inputfile outputfile" << endl;
exit (1);
}
ifstream file_in(argv[1]); // Declare and open the input stream.
if (file_in == 0) {
cout << "Cant open input file " << argv[1] << endl;
exit (1);
}
ofstream file_out(argv[2]); // Declare and open the output stream.
if (file_out == 0) {
cout << "Cant open output file " << argv[2] << endl;
exit (1);
}
Editor buffer( &file_in, &file_out);
while (buffer.get_command())
buffer.run_command();
}
Editor::Editor(ifstream *file_in, ofstream *file_out)
{
infile = file_in;
outfile = file_out;
};
bool Editor::get_command( )
{
if (current != NULL)
cout << current_position << " : "<< current->entry.c_str( ) << "\n??" << flush;
else
cout << "File is empty.\n??" << flush;
cin >> user_command; // ignores white space and gets command
user_command = tolower(user_command);
while(cin.get( ) != '\n')
; // ignore user’s enter key
if(user_command == 'q')
return false;
else
return true;
};
template <class List_entry>
void Editor::run_command( )
{
string temp_string;
cout << "Press h or ? for help or enter a valid command: ";
if(user_command=='b'){
if (empty( ))
cout << " Warning: empty buffer " << endl;
else
while (previous_line( ) == success);
goto point;;}
if(user_command=='c'){
if (empty( ))
cout << " Warning: Empty file" << endl;
else if (change_line( ) != success)
cout << " Error: Substitution failed " << endl;
goto point;;}
if(user_command=='d'){
if (remove(current_position, temp_string) != success)
cout << " Error: Deletion failed " << endl;
goto point;;}
if(user_command=='e'){
if(empty())
cout<<"Warning: Buffer is empty"<<endl
else
while (next_line( ) == success)
;
goto point;}
if(user_command=='f'){
if (empty( )) cout << " Warning: Empty file" << endl;
else
find_string( );
goto point;;}
if(user_command=='g'){
if (goto_line( ) != success)
cout << " Warning: No such line" << endl;
goto point;}
if(user_command=='?'||user_command=="h"){
cout << "Valid commands are: b(egin) c(hange) d(el) e(nd)"
<< endl
<< "f(ind) g(o) h(elp) i(nsert) l(ength) n(ext) p(rior) " << endl
<< "q(uit) r(ead) s(ubstitute) v(iew) w(rite) " << endl;}
if(user_command=='i'){
if (insert_line( ) != success)
cout << " Error: Insertion failed " << endl;
goto point;;}
if(user_command=='l'){
cout << "There are " << size( ) << " lines in the file." << endl;
if (!empty( ))
cout << "Current line length is "<< strlen((current->entry).c_str( )) << endl;
goto point;;}
if(user_command=='n'){
if (next_line( ) != success)
cout << " Warning: at end of buffer" << endl;
goto point;;}
if(user_command=='p'){
if (previous_line( ) != success)
cout << " Warning: at start of buffer" << endl;
goto point;;}
if(user_command=='r'){
read_file( );
goto point;;}
if(user_command=='s'){
if (substitute_line( ) != success)
cout << " Error: Substitution failed " << endl;
goto point;;}
if(user_command=='v'){
traverse(write);
goto point;;}
if(user_command=='w'){
if (empty( ))
cout << " Warning: Empty file" << endl;
else
write_file( );
goto point;}
point:
};
void Editor::read_file( )
{
bool proceed = true;
if (!empty( )) {
cout << "Buffer is not empty; the read will destroy it." << endl;
cout << " OK to proceed? " << endl;
cout<<"(Y)es or (N)0"<<endl;
char choice;
cin>>choice;
if (choice=='y') clear( );
}
int line_number = 0, terminal_char;
while (proceed) {
ifstream read_in;
read_in.open("hw.txt");
string in_string;
read_in>>in_string;
if (terminal_char == EOF) {
proceed = false;
if (strlen(in_string.c_str( )) > 0) insert(line_number, in_string);
}
else insert(line_number++, in_string);
}
};
error_code Editor::insert_line( ){
int line_number;
cout << " Insert what line number? " << flush;
cin >> line_number;
while (cin.get( ) != 'n');
cout << " What is the new line to insert? " << flush;
string userString;
cin>>userString;
string to_insert = userString;
return insert(line_number, to_insert);
};
I tried real quick as a test to see if I can pipe my twitter feed to boost's JSON parser. No dice. My JSON parser cannot handle the following lines:
"profile_background_image_url":"http:\/\/a2.twimg.com\/profile_background_images\/4531792\/wallpaper_stock.jpg",
"url":"http:\/\/on.fb.me\/bShBVQ",
exception error: "invalid escape sequence"
"id":86162751646482432,
exception error: "expected value"
Removing the offending lines gets a populated property tree. Obviously not sufficient for twitter. Here is the code in case I declared my property tree wrong. Help?
int main (int argc, char * const argv[])
{
boost::property_tree::basic_ptree<std::string,std::string> pt;
std::ifstream f;
f.open("testJSON2a.txt");
if(!f.is_open())
{
std::cout << "Error";
return 0;
}
try
{
boost::property_tree::json_parser::read_json(f,pt);
boost::property_tree::basic_ptree<std::string,std::string>::const_iterator iter = pt.begin(),iterEnd = pt.end();
for(;iter != iterEnd;++iter)
{
std::cout << iter->first << " " << iter->second.get_value<std::string>() << std::endl;
}
}
catch(boost::property_tree::json_parser::json_parser_error &je)
{
std::cout << "Error parsing: " << je.filename() << " on line: " << je.line() << std::endl;
std::cout << je.message() << std::endl;
}
return 0;
}
The answer is to update to the latest version of boost :-). Apparently this library is far from stable. Major changes/refactors in every version.