'Write JSON txt query to file in r
query<-'{
"query": [
{
"code": "Region",
"selection": {
"filter": "item",
"values": [
"3010",
"4020"
]
}
},
{
"code": "Sex",
"selection": {
"filter": "item",
"values": [
"1",
"2"
]
}
}
],
"response": {
"format": "json-stat2"
}
}'
Now - how can I write the query string to file and retrieve it. So far I've tried writelines, save etc, but I retrieve multiple strings rather than one long string.
Solution 1:[1]
To answer a question in the title:
Yes, there IS a way to search a string.
To look for any single character (for example, decimal point), use find.
To look for any one of the list of characters (for example, digits) use find_first_of.
Solution 2:[2]
And to answer the question body, if you wish to know what "type" of thing a string contains you have two options:
- try to convert it to that type (using istringstream and operator >>)
- use a regular expression (or other pattern matching algorithm)
As already noted to you, this takes the effort on your part to clearly specify what uniquely constitutes each "type" of thing you wish to identify.
For example. In C++, 1 is an int, 1.0 is a double, etc.
Solution 3:[3]
you could do a rough check, find_first_not_of("01234567890.") to see if it looks like a number or not. Then do lexical_cast (or stringstream <<) and see if it succeeds. If not then assume string.
Probably should do 0123456789 (not .) to see if its an integer, then if the first_not_of is "." do a lexicalcast as float else treat it as character string
probably sniff at first char to see if '-'
Solution 4:[4]
It seems you want a parser that infers the type of the expression. This can be accomplished by trying different conversions and see if they succeed. Whenever they fail, jump to the next conversion. So a 1 would be a std::uint8_t, but a -1 would be a std::int8_t, a 1.0 would be a float while a 1e+40 would be a double and so forth.
Fortunately C++17 added a function that does close to what you want: std::from_chars.
#include <charconv>
#include <string>
#include <variant>
#include <optional>
#include <cstdint>
namespace {
using Value = std::variant<
long double, double, float,
std::uint64_t, std::int64_t,
std::uint32_t, std::int32_t,
std::uint16_t, std::int16_t,
std::uint8_t, std::int8_t,
std::string // last resort if nothing works
>;
template <typename T>
std::optional<T> parse_as(char const* const begin, char const* const end) {
if (begin == end) return std::nullopt;
T value{};
auto const [ptr, ec] = std::from_chars(begin,end,value);
if (ec == std::errc::result_out_of_range || ec == std::errc::invalid_argument || ptr != end) {
return std::nullopt;
}
return value;
}
Value parse(std::string const& str) {
auto const b = str.data();
auto const e = str.data() + str.size();
if (auto const r = parse_as<std::uint8_t>(b,e)) return *r;
if (auto const r = parse_as<std::int8_t>(b,e)) return *r;
if (auto const r = parse_as<std::uint16_t>(b,e)) return *r;
if (auto const r = parse_as<std::int16_t>(b,e)) return *r;
if (auto const r = parse_as<std::uint32_t>(b,e)) return *r;
if (auto const r = parse_as<std::int32_t>(b,e)) return *r;
if (auto const r = parse_as<std::uint64_t>(b,e)) return *r;
if (auto const r = parse_as<std::int64_t>(b,e)) return *r;
if (auto const r = parse_as<float>(b,e)) return *r;
if (auto const r = parse_as<double>(b,e)) return *r;
if (auto const r = parse_as<long double>(b,e)) return *r;
return str;
}
}
Here is a small test that shows how this works:
#include <iostream>
// helper type
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
void show(std::string const& str) {
std::visit(overloaded {
[](std::uint8_t const arg) {
std::cout << int{arg} << "\tsize: " << sizeof(arg) << "\n";
},
[](std::int8_t const arg) {
std::cout << int{arg} << "\tsize: " << sizeof(arg) << "\n";
},
[](auto const arg) {
std::cout << arg << "\tsize: " << sizeof(arg) << "\n";
}
}, parse(str));
}
int main() {
show("hello");
show("64");
show("7000");
show("-7000");
show("-127");
show("1.0");
show("1e+40");
show("1e+400");
}
This will correctly print:
hello size: 32
64 size: 1
7000 size: 2
-7000 size: 2
-127 size: 1
1 size: 4
1e+40 size: 8
1e+400 size: 16
Here is a live demo.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Vlad Feinstein |
| Solution 2 | DĂșthomhas |
| Solution 3 | pm100 |
| Solution 4 | bitmask |
