I'm using boost::lexical_cast<std::string>(double) for converting doubles to string, generating JSON serialized byte stream, that is (on remote side) parsed by .NET.
I'm able to force the .NET to use InvariantCulture for parsing, thereby returning predictable result on every possible language.
However, I was not able to find this guarantee in boost::lexical_cast documentation. I tried it a little bit, and it works the same way for different locales set. But, I cannot be sure only from few tests, am I missing something in the documentation, or this cannot be guaranted at all, and I have to use something else?
EDIT:
I've found an issue.
std::locale::global(std::locale("Czech"));
std::cout << boost::lexical_cast<std::string>(0.15784465) << std::endl;
returns 0,15784465, and that is undesired. Can I force the boost::lexical_cast<> not to be aware of locales?
Can I force the boost::lexical_cast<> not to be aware of locales?
No, I don't think that is possible. The best you can do is call
std::locale::global(std::locale::classic());
to set the global locale to the "C" locale as boost::lexical_cast relies on the global locale. However, the problem is if somewhere else in the code the global locale is set to something else before calling boost::lexical_cast, then you still have the same problem.
Therefore, a robust solution would be imbue a stringstream like so, and you can be always sure that this works:
std::ostringstream oss;
oss.imbue(std::locale::classic());
oss.precision(std::numeric_limits<double>::digits10);
oss << 0.15784465;
A better solution to this problem is to use a boost::locale instead of a std::locale as the globale locale. From the documentation:
Setting the global locale has bad side effects... it affects even printf and libraries like boost::lexical_cast giving incorrect or unexpected formatting. In fact many third-party libraries are broken in such a situation.
Unlike the standard localization library, Boost.Locale never changes the basic number formatting, even when it uses std based localization backends, so by default, numbers are always formatted using C-style locale. Localized number formatting requires specific flags.
Boost locale requires you to specify explicitly when you want numeric formatting to be locale aware, which is more consistent with recent library decisions like std::money_put.
Related
NOTE: This is a rather naïve question on purpose.
During debugging and logging in a Qt5 C++ application it is useful to print the value of internal variables, and in Qt the common way is to use qDebug() with friends like this:
qDebug()<<"The value was: "<< myVar;
// Usually works well even for built-in Qt types
This seems to work for many built-in Qt5 specific types, and even pointers as well, however in the cases where instead of outputting a log, we are in fact building a string this becomes much more cumbersome.
QString myString= "The value was: "+myVar;
// Usually doesn't work well for built-in Qt types
So the question is, what is a good general way to get the equivalent string representation of built-in Qt types as you would get from streaming them to qDebug()?
Or "what is the equivalent to Java toString() for Qt types"?
From QDebug class documentation I could find that it has constructor
QDebug::QDebug(QString *string)
Constructs a debug stream that writes to the given string
So this should work:
QString myString;
QDebug stream(&myString);
stream <<"The value was: "<< myVar;
The format and contents of Qt debug output are not a part of the API. They can change at any time. You will have to audit the output each and every time you update Qt, otherwise you must not depend on it other than for debugging. That's why the APIs make it purposefully cumbersome to convert between debug output and strings.
Instead, implement your own QTextStream operators for types that you need, and use the stream to build the strings.
Is it possible to get the pointer to the string stored in string stream object . Basically i want to copy the string from that location into another buffer ..
I found that i can get the length from below code
myStringStreamObj.seekg(0, ios::end);
lengthForStringInmyStringStreamObj = myStringStreamObj.tellg();
I know i can always domyStringStreamObj.str().c_str(). However my profiler tells me this code is taking time and i want to avoid it . hence i need some good alternative to get pointer to that string.
My profiler also tells me that another part of code where is do myStringStreamObj.str(std::string()) is slow too . Can some one guide me on this too .
Please , I cant avoid stringstream as its part of a big code which i cant change / dont have permission to change .
The answer is "no". The only documented API to obtain the formatted string contents is the str() method.
Of course, there's always a small possibility that whatever the compiler or platform you're using might have its own specific non-standard and/or non-documented methods for accessing the internals of a stringstream object; which might be faster. Because your question did not specify any particular compiler or implementation, I must conclude that you are looking for a portable, standards-compliant answer; so the answer in that case is a pretty much a "no".
I would actually be surprised if any particular compiler or platform, even some who might have a "reputation" for poisonings language standards <cough>, would offer any alternatives. I would expect that all implementations would prefer to keep the internal stringstream moving gears private, so that they can be tweaked and fiddled with, in future releases, without breaking binary ABI compatibility.
The only other possibility you might want to investigate is to obtain the contents of the stringstream using its iterators. This is, of course, an entirely different mechanism for pulling out what's in a stringstream; and is not as straightforward as just calling one method that hands you the string, on a silver platter; so it's likely to involve a fairly significant rewrite of your code that works with the returned string. But it is possible that iterating over what's in the stringstream might turn out to be faster since, presumably, there will not be any need for the implementation to allocate a new std::string instance just for str()'s benefit, and jamming everything inside it.
Whether or not iterating will be faster in your case depends on how your implementation's stringstream works, and how efficient the compiler is. The only way to find out is to go ahead and do it, then profile the results.
I can not provide a portable, standards compliant method.
Although you can't get the internal buffer you can provide your own.
According to the standard setting the internal buffer of a std::stringbuf object has implementation defined behaviour.
cplusplus.com: std::stringbuf::setbuf()
As it happens in my implementation of GCC 4.8.2 the behaviour is to use the external buffer you provide instead if its internal std::string.
So you can do this:
int main()
{
std::ostringstream oss;
char buf[1024]; // this is where the data ends up when you write to oss
oss.rdbuf()->pubsetbuf(buf, sizeof(buf));
oss << "Testing" << 1 << 2 << 3.2 << '\0';
std::cout << buf; // see the data
}
But I strongly advise that you only do stuff like this as a (very) temporary measure while you sort out something more efficient that is portable according to the standard.
Having said all that I looked at how my implementation implements std::stringstream::str() and it basically returns its internal std::string so you get direct access and with optimization turned on the function calls should be completely optimized away. So this should be the preferred method.
Can I make all std::string in my application support Unicode with Boost.Locale? After reading the documentation I can say yes. But I don't understand how it works. The main question is can I still use boost string algorithms library or Boost.Lexical_Cast libraries? If yes, why I need boost::locale::to_upper and similar format methods, if I have these methods in boost string algorithm library.
Yes, you can make all strings in your application Unicode encoded with Boost.Locale.
To make it work you imbue the locale into the string, or set the default global locale to your new unicode-based locale (generated by Boost.Locale).
See here for how to do that: http://www.boost.org/libs/locale/doc/html/locale_gen.html
and http://www.boost.org/libs/locale/doc/html/faq.html
The string manipulation APIs in Boost.Locale are different to the ones provided in the Boost string algorithm library.
See here for why the Boost.Locale functions are better: http://www.boost.org/libs/locale/doc/html/conversions.html
You can still use boost::lexical_cast, provided you set the global locale correctly (as, if I recall correctly, you can't explicitly pass a locale object to Boost.LexicalCast).
Keep in mind however that this will 'break' some cases, for example, when converting an integer to a string, instead of using the C locale (as was probably your previous default), it will use a different one, which may insert separators etc. When doing conversions that are NOT displayed to the user, you may wish to use std::stringstream et al directly to avoid these unwanted formatting changes.
I highly suggest you read the Boost.Locale documentation in full, as it should address most of your concerns (especially the FAQ, generation backend information, etc.).
Is there an obvious way to perform currency formatting in C++ ?
For example: 1978879 would become 1'978'879
Thanks
Short answer:
int value = 1978879;
std::cout.imbue(std::locale(""));
std::cout << value << std::endl;
Locales are responsible for formatting. Any stream can be imbued with a locale; by default they use the global locale, which by default is the "C" locale which doesn't use any thousands separators. By creating a locale instance with the empty string as the parameter we use the user's locale, which in your case will likely be Swiss.
You can also specify an explicit locale name, but the names are different depending on your platform (Linux/Windows), and not all systems support all locales.
If you want to get a string, the easiest way is probably to use a stringstream (from the <sstream> header):
std::ostringstream stream;
stream.imbue(std::locale(""));
stream << value;
std::string stringValue = stream.str();
Though you can also use the locale's facets directly, but that's more complicated.
You could also set the global locale, which will be used by all streams (unless they're specifically imbued with a different locale):
std::locale::global(std::local(""));
Take a look at the standard C++ localization library. It's not that straightforward but you can probably achieve that through the num_get/numpunct facets.
I'm porting an existing Windows application to Linux.
The most of the OS APIs\ Microsoft non-standard extension functions can be easily (more or less...) replaced by equivalent Linux\ GCC APIs, however, I don't know how to deal with sprintf_s which gets variable numbers of arguments.
Does anyone have an idea (If you can please put the code example as well) for that?
Thank you all in advance.
First, can you just port your code to use C++ iostreams instead (for example ostringstream)? This would completely remove all the possible issues with the sprintf line of functions, and if there are a limited number of call points is probably the best option.
If that isn't an option: The sprintf_s function is basically a helper to prevent mistakes (and external abuse to cause buffer overflows. From http://msdn.microsoft.com/en-us/library/ce3zzk1k%28VS.80%29.aspx we learn that it does two things: It checks the format string for valid formats (this doesn't mean it does type checking - it still can't do that), and it allows a max length to be specified.
The best replacement will be snprintf which does have limitations compared to sprintf_s. It won't do format string validation. And not all versions guarantee that the final string will be null terminated: You always want to also store a null into the last character of your buffer after the call to ensure that the final string is null terminated.
Add to end of your header file or beginning of source file:
#ifndef _WIN32
#define sprintf_s(dest,len,format,...) sprintf(dest,format,__VA_ARGS__)
#endif
snprintf has the same signature, but AFAIK it behaves in a slightly different way.
sprintf_s is just a "secure" version (takes buffer length as extra argument) of sprintf , cant you just use sprintf for your port ?
Why not just provide a conditionally compiled implementation of sprintf_s for Linux? This implementation could simply ignore the extra argument and call through to sprintf().