C++ RedisClient : how does RedisValue.toInt() work? - c++

This is about RedisClient, which is a C++ client.
I know that you can't store integers in Redis (that are internally converted).
RedisSyncClient::command itself does not support integers as RedisBuffer can't be initialized with int, so:
redis->command("SET", "mykey", 1);
won't compile (you need to add numbers as string).
However RedisValue can be initialized with int (not sure when it is used) and it contains a public "toInt()" method:
redis->command("SET", "mykey", "1");
result = redis->command("GET", "mykey");
cout << "INT: " << result.toInt() << " , STR: " << result.toString() << endl;
INT: 0 , STR : 1
At first I thought that internally strings were being converted to int, but it always return "0". Testing "RedisValue.isInt()" it seems it fails to recognize numbers as it returns "false".
What is the intention of "toInt()" if numbers are only seen (by this library) as strings?
Am I using it incorrectly?
Is this a work-in-progress feature?

Now things make sense to me...
It seems that it may be used for redis responses like:
result = redis->command("EXISTS", "mykey");
cout << "? " << result.isInt() << endl;
? 1
In this case toInt() works as expected.
I just need to look into redis documentation and see which commands return int. It is not designed to be used with "normal" values.
(sorry to answer my own question, I would be happy to accept other answers if they cover things I missed out).

Related

bulletproof use of from_chars()

I have some literal strings which I want to convert to integer and even double. The base is 16, 10, 8, and 2.
At this time, I wonder about the behavior of std::from_chars() - I try to convert and the error code inside from_chars_result return holds success - even if it isn't as shown here:
#include <iostream>
#include <string_view>
#include <charconv>
using namespace std::literals::string_view_literals;
int main()
{
auto const buf = "01234567890ABCDEFG.FFp1024"sv;
double d;
auto const out = std::from_chars(buf.begin(), buf.end(), d, std::chars_format::hex);
if(out.ec != std::errc{} || out.ptr != buf.end())
{
std::cerr << buf << '\n'
<< std::string(std::distance(buf.begin(), out.ptr), ' ') << "^- here\n";
auto const ec = std::make_error_code(out.ec);
std::cerr << "err: " << ec.message() << '\n';
return 1;
}
std::cout << d << '\n';
}
gives:
01234567890ABCDEFG.FFp1024
^- here
err: Success
For convenience also at coliru.
In my use case, I'll check the character set before but, I'm not sure about the checks to make it bulletproof. Is this behavior expected (maybe my English isn't sufficient, or I didn't read carefully enough)? I've never seen such checks on iterators on blogs etc.
The other question is related to different base like 2 and 8. Base of 10 and 16 seems to be supported - what would be the way for the other two bases?
Addendum/Edit:
Bulletproof here means that I can have nasty things in the string. The obvious thing for me is that 'G' is not a hex character. But I would have expected an appropriate error code in some way! The comparison out.ptr != buf.end() I've never seen in blogs (or I didn't read the right ones :)
If I enter a crazy long hex float, at least a numerical result out of range comes up.
By bulletproof I also mean that I can find such impossible strings by length, for example, so that I can save myself the call to from_chars() - for float/doubles and integers (here I would 'strlen' compare digits10 from std::numeric_limits).
The from_chars utility is designed to convert the first number it finds in the string and to return a pointer to the point where it stopped. This allows you to parse strings like "42 centimeters" by first converting the number and then parsing the rest of the string yourself for what comes after it.
The comparison out.ptr != buf.end() I've never seen in blogs (or I didn't read the right ones :)
If you know that the entire string should be a number, then checking that the pointer in the result points to the end of the string is the normal way to ensure that from_chars read the entire string.

Cout unsigned char

I'm using Visual Studio 2019: why does this command do nothing?
std::cout << unsigned char(133);
It literally gets skipped by my compiler (I verified it using step-by-step debug):
I expected a print of à.
Every output before the next command is ignored, but not the previous ones. (std::cout << "12" << unsigned char(133) << "34"; prints "12")
I've also tried to change it to these:
std::cout << unsigned char(133) << std::flush;
std::cout << (unsigned char)(133);
std::cout << char(-123);
but the result is the same.
I remember that it worked before, and some of my programs that use this command have misteriously stopped working... In a blank new project same result!
I thought that it my new custom keyboard layout could be the cause, but disabling it does not change so much.
On other online compilers it works properly, so may it be a bug of Visual Studio 2019?
The "sane" answer is: don't rely on extended-ASCII characters. Unicode is widespread enough to make this the preferred approach:
#include <iostream>
int main() {
std::cout << u8"\u00e0\n";
}
This will explicitly print the character à you requested; in fact, that's also how your browser understands it, which you can easily verify by putting into e.g. some unicode character search, which will result in LATIN SMALL LETTER A WITH GRAVE, with the code U+00E0 which you can spot in the code above.
In your example, there's no difference between using a signed or unsigned char; the byte value 133 gets written to the terminal, but the way it interprets it might differ from machine to machine, basing on how it's actually set up to interpret it. In fact, in a UTF-8 console, this is simply a wrong unicode sequence (u"\0x85" isn't a valid character) - if your OS was switched to UTF-8, that might be why you're seeing no output.
You can try to use static_cast
std::cout << static_cast<unsigned char>(133) << std::endl;
Or
std::cout << static_cast<char>(133) << std::endl;
Since in mine all of this is working, it's hard to pinpoint the problem, the common sense would point to some configuration issue.

sf::String put into std::map key doesn't work - the vaule is not saved into map [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
as I wrote in the topic - I try to put sf::String into map first argument and it does not work. Here's the code:
void Flashcards::add(sf::String sf_string) {
std::string text = sf_string.toAnsiString();
std::pair<std::string,std::string> pairr = std::make_pair(text,"<Polish translation>");
std::cout << "Inserting: " << pairr.first << std::endl;
all_words.insert(pairr); //std::map<std::string, std::string> variable
void Flashcards::show() {
std::cout << "Flashcards:\n";
for (std::map<std::string, std::string>::iterator it = all_words.begin(); it != all_words.end(); it++)
{
std::cout << "English word: " << it->first
<< " " << "Polish word: " << it->second << std::endl;
}
The result in console is:
Inserting: //a word//
Flashcards:
Polish word: <Polish translation>
Instead of needed:
Inserting: hello
Flashcards:
English word: //a word// Polish word: <Polish translation>
Here are the variations I have already tried:
1) I switched the arguments so it looked like this: std::make_pair("<Polish translation>",text); and it works - hardcoded key and the value are both showed in the console (but I don't want hardcoding, what is obvious).
2) Note that this line: std::cout << "Inserting: " << pairr.first << std::endl; shows that the key value is converted into std::string correctly - calling this will show value we have just typed on the keyboard.
3) I tried to send the sf::String value directly to the std::make_pair() method, it works exactly the same as putting std::string there.
Can somebody say how to make this work?
The string you are providing as an argument to the add method obviously ends with a \r (carriage return) character, probably because you are reading it from a Windows text file using a Unix/Linux execution environment. If you capture the output of your program in a file and look at it with a hexdumper (such as hd), you should immediately see what is going on.
It certainly has nothing to do with your use of the C++ standard library. However, you don't need to go to all that work to insert an entry into a std::map. Just do this:
all_words[key] = value;
As long as key has the right type (or there is an automatic conversion), that will do precisely what you want in a single line easily-understood line, and probably more efficiently as well.

Insert values into a string without using sprintf or to_string

Currently I only know of two methods to insert values into a C++ string or C string.
The first method I know of is to use std::sprintf() and a C-string buffer (char array).
The second method is to use something like "value of i: " + to_string(value) + "\n".
However, the first one needs the creation of a buffer, which leads to more code if you just want to pass a string to a function. The second one produces long lines of code, where a string gets interrupted every time a value is inserted, which makes the code harder to read.
From Python I know the format() function, which is used like this:
"Value of i: {}\n".format(i)
The braces are replaced by the value in format, and further .format()'s can be appended.
I really like Python's approach on this, because the string stays readable, and no extra buffer needs to be created. Is there any similar way of doing this in C++?
Idiomatic way of formatting data in C++ is with output streams (std::ostream reference). If you want the formatted output to end up in a std::string, use an output string stream:
ostringstream res;
res << "Value of i: " << i << "\n";
Use str() member function to harvest the resultant string:
std::string s = res.str();
This matches the approach of formatting data for output:
cout << "Value of i: " << i << "\n";

Parse int to string with stringstream

Well!
I feel really stupid for this question, and I wholly don't mind if I get downvoted for this, but I guess I wouldn't be posting this if I had not at least made an earnest attempt at looking for the solution.
I'm currently working on Euler Problem 4, finding the largest palindromic number of two three-digit numbers [100..999].
As you might guess, I'm at the part where I have to work with the integer I made. I looked up a few sites and saw a few standards for converting an Int to a String, one of which included stringstream.
So my code looked like this:
// tempTotal is my int value I want converted.
void toString( int tempTotal, string &str )
{
ostringstream ss; // C++ Standard compliant method.
ss << tempTotal;
str = ss.str(); // Overwrite referenced value of given string.
}
and the function calling it was:
else
{
toString( tempTotal, store );
cout << loop1 << " x " << loop2 << "= " << store << endl;
}
So far, so good. I can't really see an error in what I've written, but the output gives me the address to something. It stays constant, so I don't really know what the program is doing there.
Secondly, I tried .ToString(), string.valueOf( tempTotal ), (string)tempTotal, or simply store = temptotal.
All refused to work. When I simply tried doing an implicit cast with store = tempTotal, it didn't give me a value at all. When I tried checking output it literally printed nothing. I don't know if anything was copied into my string that simply isn't a printable character, or if the compiler just ignored it. I really don't know.
So even though I feel this is a really, really lame question, I just have to ask:
How do I convert that stupid integer to a string with the stringstream? The other tries are more or less irrelevant for me, I just really want to know why my stringstream solution isn't working.
EDIT:
Wow. Seriously. This is kind of embarrassing. I forgot to set my tempTotal variable to something. It was uninitialized, so therefore I couldn't copy anything and the reason the program gave me either a 0 or nothing at all.
Hope people can have a laugh though, so I think this question would now be better suited for deletion since it doesn't really serve a purpose unless xD But thanks to everybody who tried to help me!
Have you tried just outputting the integer as is? If you're only converting it to a string to output it, then don't bother since cout will do that for you.
else
{
// toString( tempTotal, store ); // Skip this step.
cout << loop1 << " x " << loop2 << "= " << tempTotal << endl;
}
I have a feeling that it's likely that tempTotal doesn't have the value you think it has.
I know this doesn't directly answer your question but you don't need to write your own conversion function, you can use boost
#include <boost/lexical_cast.hpp>
using boost::lexical_cast;
//usage example
std::string s = lexical_cast<std::string>(tempTotal);
Try the following:
string toString(int tempTotal)
{
ostringstream ss;
ss << tempTotal;
return ss.str();
}
string store = toString(tempTotal);
If you want to output the integer, you don't even need to convert it; just insert it into the standard output:
int i = 100;
cout << i;
If you want the string representation, you're doing good. Insert it into a stringstream as you did, and ask for it's str().
If that doesn't work, I suggest you minimize the amount of code, and try to pinpoint the actual problem using a debugger :)
Short answer: your method to convert an int to a string works. Got any other questions?