How to convert string to rapid json value - c++11

I am using rapidjson library to encode and deconde the json.
I have received the string lets say string Str = "msisdn-123456789";
i want to covert this into a rapidjson value but it says parsing error. and value type is still kNullType
I am using below code snippest.
std::string Str = "msisdn-123456789";
rapidjson::Document newDoc;
newDoc.Parse(Str.c_str());
rapidjson::Value value(rapidjson::kNullType);
value.CopyFrom(newDoc, newDoc.GetAllocator());
cout << "Type of value" << static_cast<uint32_t>(value.GetType()) << endl;
The output is kNullType (0) .
How can i convert string to rapidjson value ?

std::string Str = "msisdn-123456789"; is not a valid JSON. So parsing it will have an null value at the document root.
For constructing a Value by std::string s, just
Value v(s, allocator); // When RAPIDJSON_HAS_STDSTRING=1
Value v(s.c_str(), s.size(), allocator); // Otherwise

Related

Why does an error occur when I try to test if a member variable (string) in a class is empty?

I'm working on a project and need to test one of my class' member variables to verify that the user did indeed enter a string.
I've also tried using (patronName == '') and (patronName == "") but have had no luck.
Edit: Using "\n" fixes the error but the program ends without allowing the user to enter a name.
std::string Restaurant::getPatronName()
{
bool controlFlag = true;
do
{
getline(std::cin,patronName);
if ((std::cin.fail()) || (patronName == '\n'))
{
std::cout << "You must enter a name!" << std::endl;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
else
{
controlFlag = false;
}
} while (controlFlag);
return patronName;
}
The function should read and store the name entered by the user into patronName. When trying to build, I get an error that says "no match for 'operator=='". Could this be because the object called in main is a pointer of type Restaurant?
Besides the type mismatch between the character '\n' and the std::string patronName, we can find at https://en.cppreference.com/w/cpp/string/basic_string/getline that std::getline(input, str, delim);
Extracts characters from input and appends them to str until […] the next available input character is delim, […], in which case the delimiter character is extracted from input, but is not appended to str.
So there won't be any '\n' character, if delim is the newline, in the first place.
You can use std::basic_string::empty() to check if a string is empty.
What happens with '\n' is you are comparing a string with a char, which, i suspect, there is no operator== defined for this case. If you are sure the string isn't empty, you can call operator[] formerName[0], which returns a char.
You have to write patronName == "\n" because you cannot compare string and character

Do postfix operators return lvalue when applied on ostream_iterator?

Isn't the foll code given in C++ Primer incorrect ?
ostream_iterator<int> out_iter(cout, " ");
for (auto e : vec)
*out_iter++ = e; // the assignment writes this element to cout
cout << endl;
The postfix operator returns the old value, not a reference then how can it be made to act as an lvalue ?
Please correct if I am wrong
According to reference http://en.cppreference.com/w/cpp/iterator/ostream_iterator/operator_arith
ostream_iterator& operator++();
ostream_iterator& operator++( int );
but operator* and operators ++ of ostream_iterator do nothing, they only return reference to *this, so you can write this
for (auto e : vec)
out_iter = e; // the assignment writes this element to cout
and the output will be the same.
The code is OK as:
*out_iter++ = e;
is equal to:
*(out_iter++) = e;
so postfix increment happens first and then dereference is performed.
From operator++:
ostream_iterator& operator++();
ostream_iterator& operator++( int );
Does nothing. They make it possible for the expressions *iter++=value and
*++iter=value to be used to output (insert) a value into the underlying stream.
Return value
*this
From operator*:
ostream_iterator& operator*();
It returns the iterator itself, which makes it possible to use code
such as *iter = value to output (insert) the value into the underlying
stream.
Return value
*this
Basically, it means that *(out_iter++) returns the reference to the iterator itself so one can write to the stream in the form of *(out_iter++) = value.

Extract trailing int from string containing other characters

I have a problem in regards of extracting signed int from string in c++.
Assuming that i have a string of images1234, how can i extract the 1234 from the string without knowing the position of the last non numeric character in C++.
FYI, i have try stringstream as well as lexical_cast as suggested by others through the post but stringstream returns 0 while lexical_cast stopped working.
int main()
{
string virtuallive("Images1234");
//stringstream output(virtuallive.c_str());
//int i = stoi(virtuallive);
//stringstream output(virtuallive);
int i;
i = boost::lexical_cast<int>(virtuallive.c_str());
//output >> i;
cout << i << endl;
return 0;
}
How can i extract the 1234 from the string without knowing the position of the last non numeric character in C++?
You can't. But the position is not hard to find:
auto last_non_numeric = input.find_last_not_of("1234567890");
char* endp = &input[0];
if (last_non_numeric != std::string::npos)
endp += last_non_numeric + 1;
if (*endp) { /* FAILURE, no number on the end */ }
auto i = strtol(endp, &endp, 10);
if (*endp) {/* weird FAILURE, maybe the number was really HUGE and couldn't convert */}
Another possibility would be to put the string into a stringstream, then read the number from the stream (after imbuing the stream with a locale that classifies everything except digits as white space).
// First the desired facet:
struct digits_only: std::ctype<char> {
digits_only(): std::ctype<char>(get_table()) {}
static std::ctype_base::mask const* get_table() {
// everything is white-space:
static std::vector<std::ctype_base::mask>
rc(std::ctype<char>::table_size,std::ctype_base::space);
// except digits, which are digits
std::fill(&rc['0'], &rc['9'], std::ctype_base::digit);
// and '.', which we'll call punctuation:
rc['.'] = std::ctype_base::punct;
return &rc[0];
}
};
Then the code to read the data:
std::istringstream virtuallive("Images1234");
virtuallive.imbue(locale(locale(), new digits_only);
int number;
// Since we classify the letters as white space, the stream will ignore them.
// We can just read the number as if nothing else were there:
virtuallive >> number;
This technique is useful primarily when the stream contains a substantial amount of data, and you want all the data in that stream to be interpreted in the same way (e.g., only read numbers, regardless of what else it might contain).

Read array element and convert into string

if (RARRAY_LEN(arr) > 0)
{
VALUE str = rb_ary_entry(arr, 0);
abc = some_method(*str);
}
rb_ary_entry(arr, 0) gives me an index value. Then I want to convert that value to a string so I can pass it to the next method. I tried:
rb_str_new2(rb_ary_entry(arr, 0));
but I get error saying:
error: indirection requires pointer operand `('VALUE' (aka 'unsigned long')` `invalid`)`
`ipDict = some_method(*str)`;
Use the StringValueCStr macro to convert a Ruby String into a char* (the rb_str_new functions are for converting in the other direction).
VALUE str = rb_ary_entry(arr, 0); // str is now a Ruby String
char *c_str = StringValueCStr(str);
abc = some_method(c_str);

UTF-16 to UTF-8 using ICU library

I wanted to convert UTF-16 strings to UTF-8. I came across the ICU library by Unicode. I am having problems doing the conversion as the default is UTF-16.
I have tried using converter:
UErrorCode myError = U_ZERO_ERROR;
UConverter *conv = ucnv_open("UTF-8", &myError);
int32_t bytes = ucnv_fromUChars(conv, target, 0, (UChar*)source, numread, &myError);
char *targetLimit = target + reqdLen;
const UChar *sourceLimit = mySrc + numread;
ucnv_fromUnicode(conv,&target, targetLimit, &mySrc, sourceLimit, NULL, TRUE, &myError);
I get bytes as -(big random number)
and garbage at the original target location
What am i missing?
It's a best practice to check for errors after calls that specify a UErrorCode parameter. I would start there.
Something like...
if (U_FAILURE(status))
{
std::cout << "error: " << status << ":" << u_errorName(status) << std::endl;
}

Resources