I am writing and reading string and int values using a file-backed QSettings object.
When I later try to read the values from a different process, the values are read as strings instead of int.
This is the code I am using to write values:
QSettings settings("TestQSettings.ini", QSettings::IniFormat);
settings.setValue("AAA",QString("111"));
settings.setValue("BBB",222);
This is the file created:
[General]
AAA=111
BBB=222
This is the code I am using to read values:
QVariant qvar = settings.value("AAA");
std::cout << "AAA type " << qvar.type() << std::endl;
qvar = settings.value("BBB");
std::cout << "BBB type " << qvar.type() << std::endl;
If I run this code from the same process:
AAA type 10
BBB type 2
If I run this code from a different process:
AAA type 10
BBB type 10
I know it's possible to convert the types after they have been read.
Unfortunately, this solution will require modifying Windows legacy cross-platform code which I prefer not to modify, for example multiple calls to RegQueryValueEx().
Is it possible to store and read the type information for strings and integers?
For example, Strings will have quotes "" and integers will not:
[General]
AAA="111"
BBB=222
This problem is present on both Qt 4 and Qt 5, on Linux.
Whoa whoa, are you using .ini files or the registry?
With .ini files it's obviously impossible to know what the type was, since it's all a string. You can attempt conversion of the variant to an integer (don't use canConvert!), and assume it's an integer if it converts into one.
With the registry, QSettings will work as you expect it to.
I really don't see what the problem is. Don't use .ini files if you wish to retain type information. You'd face exactly the same problems if you wrote the code by hand in a platform-dependent manner.
You can explicitly write quoted strings into the .ini files, and check for presence of quotes when reading them back. If the quotes are not present, you can try conversion to an integer.
I solved this problem for a component which needs to save and restore variants of arbitrary type, without knowing what its clients expect. The solution was to store the variant's typeName() alongside each value:
void store(QSettings& settings, const QString& key, const QVariant& value)
{
settings.setValue(key+"value", value);
settings.setValue(key+"type", value.typeName());
}
When reading back, we also read the type name, and convert() the variant if it's not already the correct type, before returning it.
QVariant retrieve(const QSettings& settings, const QString& key)
{
auto value = settings.value(key+"value");
const auto typeName = settings.value(key+"type").toString();
const bool wasNull = value.isNull(); // NOTE 1
const auto t = QMetaType::type(typeName.toUtf8()); // NOTE 2
if (value.userType() != t && !value.convert(t) && !wasNull) {
// restore value that was cleared by the failed convert()
value = settings.value(key+"value");
qWarning() << "Failed to convert value" << value << "to" << typeName;
}
return value;
}
Notes
The wasNull variable is in there because of this niggle of convert():
Warning: For historical reasons, converting a null QVariant results in a null value of the desired type (e.g., an empty string for QString) and a result of false.
In this case, we need to ignore the misleading return value, and keep the successfully-converted null variant of the correct type.
It's not clear that UTF-8 is the correct encoding for QMetaType names (perhaps local 8-bit is assumed?); my types are all ASCII, so I just use toLatin1() instead, which might be faster. If it were an issue, I'd use QString::fromLatin1 in the store() method (instead of implicit char* to QString conversion), to ensure a clean round-trip.
If the type name is not found, t will be QMetaType::UnknownType; that's okay, because convert() will then fail, and we'll return the unconverted variant (or a null). It's not great, but it's a corner case that won't happen in normal usage, and my system will recover reasonably quickly.
Turns out the solution was very simple.
When values are written to the INI file, the type is known.
I am appending to the value "\"STRING right before SetValue
When values are read back from the INI file.
I verify that string types have the above postfix.
If they do, I chop the postfix off.
If they don't I assume they are integers instead of strings.
Works like a charm!
Thanks to you all and especially #Kuba Ober for practically handing out the solution.
Related
I'm reading the documentation of std::experimental::optional and I have a good idea about what it does, but I don't understand when I should use it or how I should use it. The site doesn't contain any examples as of yet which leaves it harder for me to grasp the true concept of this object. When is std::optional a good choice to use, and how does it compensate for what was not found in the previous Standard (C++11).
The simplest example I can think of:
std::optional<int> try_parse_int(std::string s)
{
//try to parse an int from the given string,
//and return "nothing" if you fail
}
The same thing might be accomplished with a reference argument instead (as in the following signature), but using std::optional makes the signature and usage nicer.
bool try_parse_int(std::string s, int& i);
Another way that this could be done is especially bad:
int* try_parse_int(std::string s); //return nullptr if fail
This requires dynamic memory allocation, worrying about ownership, etc. - always prefer one of the other two signatures above.
Another example:
class Contact
{
std::optional<std::string> home_phone;
std::optional<std::string> work_phone;
std::optional<std::string> mobile_phone;
};
This is extremely preferable to instead having something like a std::unique_ptr<std::string> for each phone number! std::optional gives you data locality, which is great for performance.
Another example:
template<typename Key, typename Value>
class Lookup
{
std::optional<Value> get(Key key);
};
If the lookup doesn't have a certain key in it, then we can simply return "no value."
I can use it like this:
Lookup<std::string, std::string> location_lookup;
std::string location = location_lookup.get("waldo").value_or("unknown");
Another example:
std::vector<std::pair<std::string, double>> search(
std::string query,
std::optional<int> max_count,
std::optional<double> min_match_score);
This makes a lot more sense than, say, having four function overloads that take every possible combination of max_count (or not) and min_match_score (or not)!
It also eliminates the accursed "Pass -1 for max_count if you don't want a limit" or "Pass std::numeric_limits<double>::min() for min_match_score if you don't want a minimum score"!
Another example:
std::optional<int> find_in_string(std::string s, std::string query);
If the query string isn't in s, I want "no int" -- not whatever special value someone decided to use for this purpose (-1?).
For additional examples, you could look at the boost::optional documentation. boost::optional and std::optional will basically be identical in terms of behavior and usage.
An example is quoted from New adopted paper: N3672, std::optional:
optional<int> str2int(string); // converts int to string if possible
int get_int_from_user()
{
string s;
for (;;) {
cin >> s;
optional<int> o = str2int(s); // 'o' may or may not contain an int
if (o) { // does optional contain a value?
return *o; // use the value
}
}
}
but I don't understand when I should use it or how I should use it.
Consider when you are writing an API and you want to express that "not having a return" value is not an error. For example, you need to read data from a socket, and when a data block is complete, you parse it and return it:
class YourBlock { /* block header, format, whatever else */ };
std::optional<YourBlock> cache_and_get_block(
some_socket_object& socket);
If the appended data completed a parsable block, you can process it; otherwise, keep reading and appending data:
void your_client_code(some_socket_object& socket)
{
char raw_data[1024]; // max 1024 bytes of raw data (for example)
while(socket.read(raw_data, 1024))
{
if(auto block = cache_and_get_block(raw_data))
{
// process *block here
// then return or break
}
// else [ no error; just keep reading and appending ]
}
}
Edit: regarding the rest of your questions:
When is std::optional a good choice to use
When you compute a value and need to return it, it makes for better semantics to return by value than to take a reference to an output value (that may not be generated).
When you want to ensure that client code has to check the output value (whoever writes the client code may not check for error - if you attempt to use an un-initialized pointer you get a core dump; if you attempt to use an un-initialized std::optional, you get a catch-able exception).
[...] and how does it compensate for what was not found in the previous Standard (C++11).
Previous to C++11, you had to use a different interface for "functions that may not return a value" - either return by pointer and check for NULL, or accept an output parameter and return an error/result code for "not available".
Both impose extra effort and attention from the client implementer to get it right and both are a source of confusion (the first pushing the client implementer to think of an operation as an allocation and requiring client code to implement pointer-handling logic and the second allowing client code to get away with using invalid/uninitialized values).
std::optional nicely takes care of the problems arising with previous solutions.
I often use optionals to represent optional data pulled from configuration files, that is to say where that data (such as with an expected, yet not necessary, element within an XML document) is optionally provided, so that I can explicitly and clearly show if the data was actually present in the XML document. Especially when the data can have a "not set" state, versus an "empty" and a "set" state (fuzzy logic). With an optional, set and not set is clear, also empty would be clear with the value of 0 or null.
This can show how the value of "not set" is not equivalent to "empty". In concept, a pointer to an int (int * p) can show this, where a null (p == 0) is not set, a value of 0 (*p == 0) is set and empty, and any other value (*p <> 0) is set to a value.
For a practical example, I have a piece of geometry pulled from an XML document that had a value called render flags, where the geometry can either override the render flags (set), disable the render flags (set to 0), or simply not affect the render flags (not set), an optional would be a clear way to represent this.
Clearly a pointer to an int, in this example, can accomplish the goal, or better, a share pointer as it can offer cleaner implementation, however, I would argue it's about code clarity in this case. Is a null always a "not set"? With a pointer, it is not clear, as null literally means not allocated or created, though it could, yet might not necessarily mean "not set". It is worth pointing out that a pointer must be released, and in good practice set to 0, however, like with a shared pointer, an optional doesn't require explicit cleanup, so there isn't a concern of mixing up the cleanup with the optional having not been set.
I believe it's about code clarity. Clarity reduces the cost of code maintenance, and development. A clear understanding of code intention is incredibly valuable.
Use of a pointer to represent this would require overloading the concept of the pointer. To represent "null" as "not set", typically you might see one or more comments through code to explain this intention. That's not a bad solution instead of an optional, however, I always opt for implicit implementation rather than explicit comments, as comments are not enforceable (such as by compilation). Examples of these implicit items for development (those articles in development that are provided purely to enforce intention) include the various C++ style casts, "const" (especially on member functions), and the "bool" type, to name a few. Arguably you don't really need these code features, so long as everyone obeys intentions or comments.
I'm trying to write an algorithm that iterates recursively through a directory and compares each folder, sub-folder and file name to a user-defined regex object.
I've found this piece of code for the iteration part:
path p(FilePath);
for (directory_entry& x : recursive_directory_iterator(p))
std::cout << x.path() << '\n';
Where Filepath is the directory path defined by the user at runtime.
It works great to print out paths on the console, but I can't figure out a way to use path() to do what I want, which would be to assign its value to a string and then compare that string to my regex object.
I've been looking at other member function in boost::filesystem::directory_entry but I'm not really having any luck so far.
Could anyone point me in the right direction?
Thanks.
EDIT:
I'm dumb.
It works great to print out paths on the console, but I can't figure
out a way to use path() to do what I want, which would be to assign
its value to a string and then compare that string to my regex object.
boost::path has got a string member that either performs a conversion to a string type, or returns a const reference to the underlying storage mechanism (typically std::string) (see boost path documentation). Therefore, just call:
x.path().string()
Also, you might want to add some braces behind your for loop:
path p(FilePath);
std::string temppath;
for (directory_entry& x : recursive_directory_iterator(p))
{
temppath = x.path().string();
std::cout << temppath << std::endl;
}
The way you structured the code, std::cout would not be called as part of the loop, but only after the loop completed in its entirety... classic bug!!!
I'm trying to format a binary array: char* memblock to a hex string.
When I use the following:
fprintf(out, "0x%02x,", memblock[0]);
I get the following output:
0x7f,
When I try to use boost::format on an ofstream like so:
std::ofstream outFile (path, std::ios::out); //also tried with binary
outFile << (boost::format("0x%02x")%memblock[0]);
I get a weird output like this (seen in Vi): 0x0^?.
What gives?
Given that the character for 0x7f is CTRL-?, it looks like it's outputting the memblock[0] as a character rather than a hex value, despite your format string.
This actually makes sense based on what I've read in the documentation. Boost::format is a type-safe library where the format specifiers dictate how a variable will be output, but limited by the actual type of said variable, which takes precedence.
The documentation states (my bold):
Legacy printf format strings: %spec where spec is a printf format specification.
spec passes formatting options, like width, alignment, numerical base used for formatting numbers, as well as other specific flags. But the classical type-specification flag of printf has a weaker meaning in format.
It merely sets the appropriate flags on the internal stream, and/or formatting parameters, but does not require the corresponding argument to be of a specific type. e.g. : the specification 2$x, meaning "print argument number 2, which is an integral number, in hexa" for printf, merely means "print argument 2 with stream basefield flags set to hex" for format.
And presumably, having the field flag set to hex doesn't make a lot of sense when you're printing a char, so it's ignored. Additionally from that documentation (though paraphrased a little):
The type-char does not impose the concerned argument to be of a restricted set of types, but merely sets the flags that are associated with this type specification. A type-char of p or x means hexadecimal output but simply sets the hex flag on the stream.
This is also verified more specifically by the text from this link:
My colleagues and I have found, though, that when a %d descriptor is used to print a char variable the result is as though a %c descriptor had been used - printf and boost::format don't produce the same result.
The Boost documentation linked to above also explains that the zero-padding 0 modifier works on all types, not just integral ones, which is why you're getting the second 0 in 0x0^? (the ^? is a single character).
In many ways, this is similar to the problem of trying to output a const char * in C++ so that you see a pointer. The following code:
#include <iostream>
int main() {
const char *xyzzy = "plugh";
std::cout << xyzzy << '\n';
std::cout << (void*)xyzzy << '\n';
return 0;
}
will produce something like:
plugh
0x4009a0
because the standard libraries know that C-style strings are a special case but, if you tell them it's a void pointer, they'll give you a pointer as output.
A solution in your specific case may be just to cast your char to an int or some other type that intelligently handles the %x format specifier:
outFile << (boost::format("0x%02x") % static_cast<int>(memblock[0]));
after saving a string into a TTree
std::string fProjNameIn, fProjNameOut;
TTree *tTShowerHeader;
tTShowerHeader = new TTree("tTShowerHeader","Parameters of the Shower");
tTShowerHeader->Branch("fProjName",&fProjNameIn);
tTShowerHeader->Fill();
I'm trying to do the following
fProjNameOut = (std::string) tTShowerHeader->GetBranch("fProjName");
which does not compile, though
std::cout << tTShowerHeader->GetBranch("fProjName")->GetClassName() << std::endl;
tells me, this Branch is of type string
is there a standard way to read a std::string from a root tree?
The solution follows below.
Imagine you have a ROOT file and you want to save an std::string to it.
TTree * a_tree = new TTree("a_tree_name");
std::string a_string("blah");
a_tree->Branch("str_branch_name", &a_string); // at this point, you've saved "blah" into a branch as an std::string
To access it:
TTree * some_tree = (TTree*)some_file->Get("a_tree_name");
std::string * some_str_pt = new std::string();
some_tree->SetBranchAddress("str_branch_name", &some_str_pt);
some_tree->GetEntry(0);
To print to standard output:
std::cout << some_str_pt->c_str() << std::endl;
Hope this helps.
You are calling tTShowerHeader->GetBranch("fProjName")-> and it compiles. That means that return type of tTShowerHeader->GetBranch() is a pointer.
Moreover, you are calling GetClassName() on that pointer and it compiles, so it's a pointer to a class type.
Even more, the std::string does not have a GetClassName() method, so it's not a std::string*. Indeed, it seems it is TBranch *. You must find appropriate method that will give you the text.
PS: Unlearn to use C-style cast in C++. C-style cast is evil, because it will do different things depending on what the type happens to be. Use the restricted static_cast, dynamic_cast, const_cast or function-style casts instead (and reinterpret_cast if you really need that, but that should be extremely rare).
Ok, this took a while but I figured out how to get the information from the tree. You cannot directly return the information, it can only be returned through the variable it was given in.
std::string fProjNameIn, fProjNameOut;
TTree *tTShowerHeader;
fProjnameIn = "Jones";
tTShowerHeader = new TTree("tTShowerHeader","Parameters of the Shower");
tTShowerHeader->Branch("fProjName",&fProjNameIn);
tTShowerHeader->Fill();//at this point the name "Jones" is stored in the Tree
fProjNameIn = 0;//VERY IMPORTANT TO DO (or so I read)
tTShowerHeader->GetBranch("fProjName")->GetEntries();//will return the # of entries
tTShowerHeader->GetBranch("fProjName")->GetEntry(0);//return the first entry
//At this point fProjNameIn is once again equal to "Jones"
In root the TTree class stores the address to the varriable used for input into it. Using GetEntry() will fill the same variable with the information stored in the TTree.
You can also use tTShowerHeader->Print() to display the number of entires for each branch.
I have an enum that I'm doing a cout on, as in: cout << myenum.
When I debug, I can see the value as an integer value but when cout spits it out, it shows up as the text representation.
Any idea what cout is doing behind the scenes? I need that same type of functionality, and there are examples out there converting enum values to string but that seems like we need to know what those values are ahead of time. In my case, I don't. I need to take any ol' enum and get its text representation. In C# it's a piece of cake; C++.. not easy at all.
I can take the integer value if I need to and convert it appropriately, but the string would give me exactly what I need.
UPDATE:
Much thanks to everyone that contributed to this question. Ultimately, I found my answer in some buried code. There was a method to convert the enum value to a string representing the actual move like "exd5" what have ya. In this method though they were doing some pretty wild stuff which I'm staying away form at the moment. My main goal was to get to the string representation.
Enum.hpp:
enum Enum {
FOO,
BAR,
BAZ,
NUM_ENUMS
};
extern const char* enum_strings[];
Enum.cpp:
const char* enum_strings[] = {
"FOO",
"BAR",
"BAZ",
"NUM_ENUMS",
0 };
Then when I want to output the symbolic representation of the enum, I use std::cout << enum_strings[x].
Thus, you do need to know the string values, but only in one placeānot everywhere you use this.
This functionality comes from the IOStreams library. std::cout is an std::ostream.
std::stringstream is an std::ostream too.
int x = 5;
std::stringstream ss;
ss << x;
// ss.str() is a string containing the text "5"