libjson parses integers incorrectly - c++

I am trying to parse following JSON data (created with JSON.stringify). I am using libJSON 7. My code follows:
wstring jsonstr = _T("{\"Id\":0,\"Note\":\"\",\"Username\":\"user\",\"Password\":\"pass\",\"Enabled\":true,\"ProfileId\":\"\",\"UserAgent\":\"\",\"LastUsage\":0,\"Failures\":0,\"Abuses\":0}");
JSONNode jsondata = libjson::parse(jsonstr);
auto i = jsondata.begin();
auto num = i->as_float();
int idIsNan = _isnan(num);// Nonzero here
Now I expect that num == (double)0, however, it equals 1.#QNAN00000000000 instead. Does anyone know how to bypass this bug?
Also if I use as_int instead of as_float, it parses data correctly; so, it looks like this bug takes place for as_float method only.

I am guessing a bit here, since you don't show all the relevant code:
Your json structure is data, json seems to be the string you are parsing. So json.begin() would be the first character in that string, not the first json value. Since that first character is double quote, it cannot be parsed as a float -> you get the nonsense you see. Maybe this is what you want:
JSONNode data = libjson::parse(json);
auto i = data.begin(); //<-- data, not json!
auto num = i->as_float();
Please remember to give all the relevant code next time, that includes definition of all used variables (in this case, 'json').
PS: The json string you posted ends with an unmatched } - that might confuse the parser.

Related

CString formatting currency

Good evening, could you tell me if a class or a method exists in MFC visual C++ which takes a CString type and formats it in currency… i.e CString str; str = _T("12345,67") and str becomes= 12.345,67 or str = 5000 and becomes str = 5.000,00
I've also tried to create a method but without success
Thanks who will be able to help me… I know it would be easier to add the points as separators where it needs, but when I need to convert the CString in double it truncates from the first point to the end.
I don't have a solution
I suggest that you use the GetCurrencyFormatEx function for this.
To quote the article:
Formats a number string as a currency string for a locale specified by name.
As for COleCurrency, you are not left to work it out for yourself. There is documentation. I admit I have not used this class, but it implies that COleCurrency::Format will do what you want:
Returns a CString that contains the formatted currency value.
Sample code is provided:
COleCurrency curA; // value: 0.0000
curA.SetCurrency(4, 500); // value: 4.0500
// value returned: 4.05
curA.Format(0, MAKELCID(MAKELANGID(LANG_CHINESE,
SUBLANG_CHINESE_SINGAPORE), SORT_DEFAULT));
// value returned: 4,05
curA.Format(0, MAKELCID(MAKELANGID(LANG_GERMAN,
SUBLANG_GERMAN_AUSTRIAN), SORT_DEFAULT));
ParseCurrency is also documented and again, a sample is provided:
// works if default locale has dot decimal point
COleCurrency cur;
cur.ParseCurrency(_T("$135.95"), 0);
ASSERT(cur == COleCurrency(135, 9500));

Get image size from traced torchscript model

When exporting a yolo5-model to torchscript (using yolo5's export.py), the input image size has to be fixed using the --imgsz-argument.
How can I access this value (the expected image size) later using torch's C++-API?
I know that the information is there: the exported model is a zip-archive in disguise and, after unzipping, the size appears in extra/config.txt.
So I could theoretically use a zip-library to retrieve this information.
However, it feels hacky and might be unstable.
You can get the files in the extra/ directory in the zip archive using an overload of the torch::jit::load method:
torch::jit::ExtraFilesMap extra_files{{"config.txt", ""}};
m_module = torch::jit::load("path/to/model.torchscript", gpu_id, extra_files);
std::cout << extra_files.at("config.txt") << std::endl;
Will yield the content of config.txt, which contains JSON, i.a. the required shape of the input image.
It should be easy to troll the desired value from that string.
Note that this solution only works if the config.txt file has been added to the zip archive explicitly.
yolov5's export.py does that.
I am not a c++ expert but this code works for me. I saved two double variables on python and was able to read them in c++. I tried to memcpy straight from the string but I wasn't able to, that's why I created this sequence of char.
torch::jit::script::Module module;
torch::jit::ExtraFilesMap extra_files{{"var1", ""}, {"var2", ""}};
module = torch::jit::load("model.pt", device, extra_files);
std::string var1_str = extra_files.at("var1");
std::string var2_str = extra_files.at("var2");
double var1;
char b[] = {var1_str[0], var1_str[1], var1_str[2], var1_str[3], var1_str[4], var1_str[5], var1_str[6], var1_str[7]};
memcpy(&var1, &b, sizeof(var1));
printf("Var1 read: %.17g\n", var1);
This is the python code I used to save the variables:
traced_script_module = torch.jit.trace(model, sample)
extra_files = {'var1': np.array(var1).tobytes(), 'var2': np.array(var2).tobytes()}
traced_script_module.save('model.pt', _extra_files=extra_files)
This was based on #pasbi answer.

Parsing a float number from JSON using nlohmann::json

I want to get a decimal number from a json file into a float variable by using the nlohmann::json library and allways get the output 86700.2031 instead of 86700.2. First I used a numeric json type:
{
"test": 86700.2,
}
and tried this way:
using json = nlohmann::json;
std::string config_path = "C:/config/default.json";
std::ifstream config_file(config_path);
json config = json::parse(config_file);
float test = config["test"]; //Output: 86700.2031
After that I changed the json type to string and tried this with the same outcome:
float test = std::stof(config["test"].get<std::string>()); //Output: 86700.2031
Reading integers or strings works fine. How do I read a float value properly?
"float" has very low precision. Never use float but use double instead. (One day you will know where you can go against that advice. Before that, use double). The result will not be exactly 86700.2 but very close to it.
Weird though that your library returns a string when the value clearly isn't a string. I'd check the documentation for what function you should call. You should never have to convert data yourself like that.

replace the occurrence of character with a seq number using boost

How can i replace multiple occurrences of a character with a string containing the occurrence number.
e.g if i have the following expression.
insert into emp values(?,?,?)
I want the following converted string.
insert into emp values(_p_1,_p_2,_p_3)
I am trying this using the boost regular expression.
Can anyone tell me how to achieve this using the boost c++ (with no or minimum iteration).
currently I am using the following approach:
std::wstring q=L"insert into emp values(?,?,?)";
auto loc = q.find(L"?");
auto len = wcslen(L"?");
auto c=1;
while(loc != std::wstring::npos)
{
q.replace(loc, len , L"_p_"+to_wstring(c));
c++;
loc = q.find(L"?");
}
cout<<q.c_str();
Please suggest better and efficient approaches.
I'd just forget regular expressions and trying to do this simple thing with Boost.
It's like asking, "how do I add 1 to a variable using Boost regular expressions"?
Best answer, IMHO, is to instead just use ++ for the task of adding 1, and to use a loop to replace special characters with strings.
string const query_format = "insert into emp values(?,?,?)";
string const params[] = {"_p_1", "_p_2", "_p3"};
string query;
string const* p = params;
for( char const c : query_format )
{
if( c == '?' ) { query += *p++; } else { query += c; }
}
// Use `query`
One might choose to wrap this up as a replace function.
Disclaimer: code not touched by compiler.
If you control the query_format string, why not instead make the placeholders compatible with Boost format.
Re the parenthetical requirement
” with no or minimum iteration
there's iteration involved no matter how you do this. You can hide the iteration behind a function name, but that's all. It's logically impossible to actually avoid the iteration, and it's trivial (completely trivial) to hide it behind a function name.

Search for presence of a blank space inside a string using find

I have the following code
std::string t = "11:05:47" (No spaces inside)
I want to check if it has an empty space in it (which it doesnt) so I am using
unsigned present = t.find(" ");
if (present!=std::string::npos)
{
//Ends up in here
}
The codes seems to think there is a blank space inside the string any suggestions on what I might be doing wrong
Here are the results
present = 4294967295
t = 11:15:36
IS there a boost library that could help me do this ? Any suggestions ?
Don't use unsigned. std::string::find returns a std::string::size_type, which is usually size_t.
std::string::size_type present = t.find(" ");
if (present!=std::string::npos) {
}
As pointed out by others, you could use C++11's auto to let the compiler deduce what the type of present should be:
auto present = t.find(" ");