float <-> std::string conversion alternative? - c++

is there any alternative to atof, strtod, lexical_cast, stringstream or sprintf?
that is:
fast
C++ way (std::string instead of char*)
safe (no buffer overrun risk)
valid (return NaN if conversion couldn't be made)
no external library (independent)
I prefer more like this , a simple function, optimized, and to the point
reason :
atof and strtod is C function and they are not returning NaN upon failure, I prefer working on std::string, so I just asking if anyone already writing some wrapper to std::string that I can use (if you don't mind).
lexical_cast has boost dependency
stringstream is slow
sprintf has buffer overflow risk and its C function

I'd look at Boost Spirit
http://www.boost.org/doc/libs/1_47_0/libs/spirit/doc/html/spirit/qi/reference/numeric/real.html
At least the benchmarks of the formatters (that is float -> string) consistently turn out as top-of-the-bill*1*
Also the exact input format specification and semantics when parsing can be configured very nicely using a policy class.
Here is my absolute min-dependency use of qi::any_real_parser<> and the list of dependendencies it touches:
#include <boost/spirit/include/qi_real.hpp>
namespace qi = boost::spirit::qi;
int main()
{
const char input[] = "3.1415926";
const char *f(input);
const char *l(f+strlen(input));
qi::any_real_parser<double> x;
double parsed;
x.parse(f, l, qi::unused, qi::unused, parsed);
return 0;
}
boost/concept
boost/config
boost/detail
boost/exception
boost/fusion
boost/iterator
boost/math
boost/mpl
boost/optional
boost/preprocessor
boost/proto
boost/range
boost/regex
boost/spirit
boost/typeof
boost/type_traits
boost/utility
boost/variant
aligned_storage.hpp,assert.hpp,blank_fwd.hpp,blank.hpp,call_traits.hpp,checked_delete.hpp,concept_check.hpp,config.hpp,cstdint.hpp,current_function.hpp,foreach_fwd.hpp,foreach.hpp,get_pointer.hpp,implicit_cast.hpp,iterator.hpp,limits.hpp,math_fwd.hpp,next_prior.hpp,noncopyable.hpp,none.hpp,none_t.hpp,optional.hpp,ref.hpp,static_assert.hpp,swap.hpp,throw_exception.hpp,type.hpp,utility.hpp,variant.hpp,version.hpp
1 e.g. http://www.boost.org/doc/libs/1_47_0/libs/spirit/doc/html/spirit/karma/performance_measurements/numeric_performance/double_performance.html

If you want to convert from numerical types to std::string there's a std::to_string function available in the latest standard.
Unfortunately as I've found out recently, in Visual Studio 2010 it is somewhat limited because there are only three overloads available for it; long double, long long, and unsigned long long. This causes issues when trying to use them from within templates.

The fast format library should be able to do the kinds of transformations you're looking for, at least for writing a float out. It does not handle parsing of a float, however.

Related

What is the equivalent of `string` in C++

In Python, there is a type named string, what is the exact equivalent of python's string in C++?
The equivalent is std::string or std::wstring declared in the <string> header file.
Though you should note that python has probably different intrinsic behavior about handling automatic conversions to UNICODE strings, as mentioned in #Vincent Savard's comment.
To overcome these problems we use additional libraries in c++ like libiconv. It's available for use on a broad number of platforms.
You should seriously note to do some better research before asking at Stack Overflow, or ask your question more clearly. std::string is ubiquitous.
You could either use std::string (see available interface here: std::string)
or use char array(or const char*) to represent a basic combination of characters that might function as a primitive string.
Do you mean the std::string family?
#include <string>
int main() {
const std::string example = "test";
std::string exclaim = example + "!";
std::cout << exclaim << std::endl;
return 0;
}

How to get a formatted std::string in c++ without length liminations

What is the best way (short, using standard libraries and easy to understand) to do this in c++:
std::string s = magic_command("%4.2f", 123.456f)
without length limitations (char s[1000] = ...)
where "%4.2f" is any c format string (which would be given to printf for example)
I am aware of the snprintf malloc combo suggested for pure c in
writing formatted data of unknown length to a string (C programming)
but is there a better, less verbose, way to do this with c++?
I am also aware of the std::ostringstream method suggested in
Convert float to std::string in C++
but I want to pass a c format string such as "%4.2f", and I could not find a way to do this with ostringstream.
You can try Boost.Format:
std::string s = boost::str(boost::format("%4.2f") % 123.456f);
It's not included in the standard, but Boost is about as standard as a non-standard library can get.
I would use a std::stringstream (in combination with setprecision) instead and use .str() afterwards to get the std::string.
C++ completely abandons the concept of format string, so there will be no standard way to do it. You could implement magic_command yourself using asprintf (its vasprintf variant actually), though.
Note that *asprintf are GNU/BSD extensions. As such, they don't exist on Windows. Also, this solution is not type-safe, and will only accept POD types (so no classes, structs or unions).
std::string magic_command(const std::string& format, ...)
{
char* ptr;
va_list args;
va_start(args, format);
vasprintf(&ptr, format.c_str(), args);
va_end(args);
std::unique_ptr<char, decltype(free)&> free_chars(ptr, free);
return std::string(ptr);
}
If you literally want to use your syntax and forgo type safety, I'd write a little wrapper class that wraps snprintf. I'd make it start out with a local, automatic buffer of some small size (say 2048?) and call snprintf once. If it succeeds, return a std::string created from that buffer. If you overran, allocate a std::string of the correct size and repeat the snprintf.
New answer 10 years later: C++20 std::format
Finally, this will be the superior choice once you can use it:
#include <format>
#include <string>
int main() {
std::cout << std::format("{:4.3}\n{:4.3}\n", 3.1, 3.1415);
}
Expected output:
3.1
3.14
This will therefore completely overcome the madness of modifying std::cout state.
The existing fmt library implements it for before it gets official support: https://github.com/fmtlib/fmt Install on Ubuntu 22.04:
sudo apt install libfmt-dev
Modify source to replace:
<format> with <fmt/core.h>
std::format to fmt::format
main.cpp
#include <iostream>
#include <fmt/core.h>
int main() {
std::cout << fmt::format("{:4.3}\n{:4.3}\n", 3.1, 3.1415);
}
and compile and run with:
g++ -std=c++11 -o main.out main.cpp -lfmt
./main.out
Output:
3.1
3.14
Old answer
All answers given are good since there seems to be no really standard way of doing what I want, I'll vote you all up, and accept my own sum up course of action:
if the string is short enough to estimate its size by hand, do it, multiply your estimative by 4, and allocate it statically.
if you can get away with stringstream + setprecision, do it since it is standard
if not, and you are willing to write and include a short helper function based on snprintf/check overflow/dynamic allocation, do it and put it into your project "utils" file
finnally consider which dependency is less restrictive for your project (maybe you are already using one of them):
if boost is less restrictive, use Boost.Format
if GNU/BSD extensions are less restrictive, use asprintf

equivalent of atoi

Is there a function that could replace atoi in c++.
I made some research and didn't find anything to replace it, the only solutions would be using cstdlib or implementing it myself
If you don't want to use Boost, C++11 added std::stoi for strings. Similar methods exist for all types.
std::string s = "123"
int num = std::stoi(s);
Unlike atoi, if no conversion can be made, an invalid_argument exception is thrown. Also, if the value is out of range for an int, an out_of_range exception is thrown.
boost::lexical_cast is your friend
#include <string>
#include <boost/lexical_cast.hpp>
int main()
{
std::string s = "123";
try
{
int i = boost::lexical_cast<int>(s); //i == 123
}
catch(const boost::bad_lexical_cast&)
{
//incorrect format
}
}
You can use the Boost function boost::lexical_cast<> as follows:
char* numericString = "911";
int num = boost::lexical_cast<int>( numericString );
More information can be found here (latest Boost version 1.47). Remember to handle exceptions appropriately.
Without boost:
stringstream ss(my_string_with_a_number); int my_res; ss >> my_res;
About as annoying as the boost version but without the added dependency. Could possibly waste more ram.
You don't say why atoi is unsuitable so I am going to guess it has something to do with performance. Anyway, clarification would be helpful.
Using Boost Spirit.Qi is about an order of magnitude faster than atoi, at least in tests done by Alex Ott.
I don't have a reference but the last time I tested it, Boost lexical_cast was about an order of magnitude slower than atoi. I think the reason is that it constructs a stringstream, which is quite expensive.
Update: Some more recent tests

Why doesn't C++ reimplement C standard functions with C++ elements/style?

For a specific example, consider atoi(const std::string &). This is very frustrating, since we as programmers would need to use it so much.
More general question is why does not C++ standard library reimplement the standard C libraries with C++ string,C++ vector or other C++ standard element rather than to preserve the old C standard libraries and force us use the old char * interface?
Its time consuming and the code to translate data types between these two interfaces is not easy to be elegant.
Is it for compatible reason,considering there was much more legacy C code than these days and preserving these C standard interfaces would make translation from C code to C++ much easier?
In addition,I have heard many other libraries available for C++ make a lot of enhancement and extensions to STL.So does there libraries support these functions?
PS: Considering much more answers to the first specific question, I edit a lot to clarify the question to outline the questions that I am much more curious to ask.
Another more general question is why do not STL reimplementate all the standard C libraries
Because the old C libraries do the trick. The C++ standard library only re-implements existing functionality if they can do it significantly better than the old version. And for some parts of the C library, the benefit of writing new C++-implementations just isn't big enough to justify the extra standardization work.
As for atoi and the like, there are new versions of these in the C++ standard library, in the std::stringstream class.
To convert from a type T to a type U:
T in;
U out;
std::stringstream sstr(in);
sstr >> out;
As with the rest of the IOStream library, it's not perfect, it's pretty verbose, it's impressively slow and so on, but it works, and usually it is good enough. It can handle integers of all sizes, floating-point values, C and C++ strings and any other object which defines the operator <<.
EDIT:In addition,I have heard many other libraries avaliable for C++ make a lot of enhancement and extensions to STL.So does there libraries support these functions?
Boost has a boost::lexical_cast which wraps std::stringstream. With that function, you can write the above as:
U out = boost::lexical_cast<U>(in);
Even in C, using atoi isn't a good thing to do for converting user input. It doesn't provide error checking at all. Providing a C++ version of it wouldn't be all that useful - considering that it wouldn't throw and do anything, you can just pass .c_str() to it and use it.
Instead you should use strtol in C code, which does do error checking. In C++03, you can use stringstreams to do the same, but their use is error-prone: What exactly do you need to check for? .bad(), .fail(), or .eof()? How do you eat up remaining whitespace? What about formatting flags? Such questions shouldn't bother the average user, that just want to convert his string. boost::lexical_cast does do a good job, but incidentally, C++0x adds utility functions to facilitate fast and safe conversions, through C++ wrappers that can throw if conversion failed:
int stoi(const string& str, size_t *idx = 0, int base = 10);
long stol(const string& str, size_t *idx = 0, int base = 10);
unsigned long stoul(const string& str, size_t *idx = 0, int base = 10);
long long stoll(const string& str, size_t *idx = 0, int base = 10);
unsigned long long stoull(const string& str, size_t *idx = 0, int base = 10);
Effects: the first two functions call strtol(str.c_str(), ptr, base), and the last three functions
call strtoul(str.c_str(), ptr, base), strtoll(str.c_str(), ptr, base), and strtoull(str.c_str(), ptr, base), respectively. Each function returns the converted result, if any. The argument ptr designates a pointer to an object internal to the function that is used to determine what to store at *idx. If the function does not throw an exception and idx != 0, the function stores in *idx the index of the first unconverted element of str.
Returns: the converted result.
Throws: invalid_argument if strtol, strtoul, strtoll, or strtoull reports that no conversion could be performed. Throws out_of_range if the converted value is outside the range of representable values for the return type.
There's no good way to know if atoi fails. It always returns an integer. Is that integer a valid conversion? Or is the 0 or -1 or whatever indicating an error? Yes it could throw an exception, but that would change the original contract, and you'd have to update all your code to catch the exception (which is what the OP is complaining about).
If translation is too time consuming, write your own atoi:
int atoi(const std::string& str)
{
std::istringstream stream(str);
int ret = 0;
stream >> ret;
return ret;
}
I see that solutions are offered that use std::stringstream or std::istringstream.
This might be perfectly OK for single threaded applications but if an application has lots of threads and often calls atoi(const std::string& str) implemented in this way that will result in performance degradation.
Read this discussion for example: http://gcc.gnu.org/ml/gcc-bugs/2009-05/msg00798.html.
And see a backtrace of the constructor of std::istringstream:
#0 0x200000007eb77810:0 in pthread_mutex_unlock+0x10 ()
from /usr/lib/hpux32/libc.so.1
#1 0x200000007ef22590 in std::locale::locale (this=0x7fffeee8)
at gthr-default.h:704
#2 0x200000007ef29500 in std::ios_base::ios_base (this=<not available>)
at /tmp/gcc-4.3.1.tar.gz/gcc-4.3.1/libstdc++-v3/src/ios.cc:83
#3 0x200000007ee8cd70 in std::basic_istringstream<char,std::char_traits<char>,std::allocator<char> >::basic_istringstream (this=0x7fffee4c,
__str=#0x7fffee44, __mode=_S_in) at basic_ios.h:456
#4 0x4000f70:0 in main () at main.cpp:7
So every time you enter atoi() and create a local varibale of type std::stringstream you will lock a global mutex and in a multithreaded application it is likely to result in waiting on this mutex.
So, it's better in a multithreaded application not to use std::stringstream. For example simply call atoi(const char*):
inline int atoi(const std::string& str)
{
return atoi(str.c_str());
}
For your example, you've got two options:
std::string mystring("4");
int myint = atoi(mystring.c_str());
Or something like:
std::string mystring("4");
std::istringstream buffer(mystring);
int myint = 0;
buffer >> myint;
The second option gives you better error management than the first.
You can write a more generic string to number convert as such:
template <class T>
T strToNum(const std::string &inputString,
std::ios_base &(*f)(std::ios_base&) = std::dec)
{
T t;
std::istringstream stringStream(inputString);
if ((stringStream >> f >> t).fail())
{
throw runtime_error("Invalid conversion");
}
return t;
}
// Example usage
unsigned long ulongValue = strToNum<unsigned long>(strValue);
int intValue = strToNum<int>(strValue);
int intValueFromHex = strToNum<int>(strHexValue,std::hex);
unsigned long ulOctValue = strToNum<unsigned long>(strOctVal, std::oct);
For conversions I find simplest to use boost's lexical_cast (except it might be too rigorously checking the validity of the conversions of string to other types).
It surely isn't very fast (it just uses std::stringstream under the hood, but significantly more convenient), but performance is often not needed where you convert values (e.g to create error output messages and such). (If you do lots of these conversions and need extreme performance, chances are you are doing something wrong and shouldn't be performing any conversions at all.)
Because the old C libraries still work with standard C++ types, with a very little bit of adaptation. You can easily change a const char * to a std::string with a constructor, and change back with std::string::c_str(). In your example, with std::string s, just call atoi(s.c_str()) and you're fine. As long as you can switch back and forth easily there's no need to add new functionality.
I'm not coming up with C functions that work on arrays and not container classes, except for things like qsort() and bsearch(), and the STL has better ways to do such things. If you had specific examples, I could consider them.
C++ does need to support the old C libraries for compatibility purposes, but the tendency is to provide new techniques where warranted, and provide interfaces for the old functions when there isn't much of an improvement. For example, the Boost lexical_cast is an improvement over such functions as atoi() and strtol(), much as the standard C++ string is an improvement over the C way of doing things. (Sometimes this is subjective. While C++ streams have considerable advantages over the C I/O functions, there's times when I'd rather drop back to the C way of doing things. Some parts of the C++ standard library are excellent, and some parts, well, aren't.)
There are all sorts of ways to parse a number from a string, atoi can easily be used with a std::string via atoi(std.c_str()) if you really want, but atoi has a bad interface because there is no sure way to determine if an error occurred during parsing.
Here's one slightly more modern C++ way to get an int from a std::string:
std::istringstream tmpstream(str);
if (tmpstream >> intvar)
{
// ... success! ...
}
The tongue in cheek answer is: Because STL is a half-hearted attempt to show how powerful C++ templates could be. Before they got to each corner of the problem space, time was up.
There are two reasons: Creating an API takes time and effort. Create a good API takes a lot of time and a huge effort. Creating a great API takes an insane amount of time and an incredible effort. When the STL was created, OO was still pretty new to the C++ people. They didn't have the ideas how to make fluent and simple API. Today, we think iterators are so 1990 but at the time, people thought "Bloody hell, why would I need that? for (int i=0; i<...) has been good enough for three decades!"
So STL didn't became the great, fluent API. This isn't all C++ fault because you can make good APIs with C++. But it was the first attempt to do that and it shows. Before the API could mature, it was turned into a standard and all the ugly shortcomings were set into stone. And on top of this, there was all this legacy code and all the libraries which already could do everything, so the pressure wasn't really there.
To solve your misery, give up on STL and have a look at the successors: Try boost and maybe Qt. Yeah, Qt is a UI library but it also has a pretty good standard library.
Since C++11, you can use std::stoi. It is like atoi but for std::string.

C++: what is the optimal way to convert a double to a string?

What is the most optimal way to achieve the same as this?
void foo(double floatValue, char* stringResult)
{
sprintf(stringResult, "%f", floatValue);
}
I'm sure someone will say boost::lexical_cast, so go for that if you're using boost, but it's basically the same as this anyway:
#include <sstream>
#include <string>
std::string doubleToString(double d)
{
std::ostringstream ss;
ss << d;
return ss.str();
}
Note that you could easily make this into a template that works on anything that can be stream-inserted (not just doubles).
http://www.cplusplus.com/reference/iostream/stringstream/
double d=123.456;
stringstream s;
s << d; // insert d into s
Boost::lexical_cast<>
On dinkumware STL, the stringstream is filled out by the C library snprintf.
Thus using snprintf formatting directly will be comparable with the STL formatting part.
But someone once told me that the whole is greater than or equal to the sum of its known parts.
As it will be platform dependent as to whether stringstream will do an allocation (and I am quite sure that DINKUMWARE DOES NOT YET include a small buffer in stringstream for conversions of single items like yours) it is truely doubtful that ANYTHING that requires an allocation (ESPECIALLY if MULTITHREADED) can compete with snprintf.
In fact (formatting+allocation) has a chance of being really terrible as an allocation and a release might well require 2 full read-modify-write cycles in a multithreaded environment unless the allocation implementation has a thread local small heap.
That being said, if I was truely concerned about performance, I would take the advice from some of the other comments above, change the interface to include a size and use snprintf - i.e.
bool
foo(const double d, char* const p, const size_t n){
use snprintf......
determine if it fit, etc etc etc.
}
If you want a std::string you are still better off using the above and instantiating the string from the resultant char* as there will be 2 allocations + 2 releases involved with the std::stringstream, std::string solution.
BTW I cannot tell if the "string" in the question is std::string or just generic ascii chars usage of "string"
The best thing to do would be to build a simple templatized function to convert any streamable type into a string. Here's the way I do it:
#include <sstream>
#include <string>
template <typename T>
const std::string to_string(const T& data)
{
std::ostringstream conv;
conv << data;
return conv.str();
}
If you want a const char* representation, simply substitute conv.str().c_str() in the above.
I'd probably go with what you suggested in your question, since there's no built-in ftoa() function and sprintf gives you control over the format. A google search for "ftoa asm" yields some possibly useful results, but I'm not sure you want to go that far.
I'd say sprintf is pretty much the optimal way. You may prefer snprintf over it, but it doesn't have much to do with performance.
Herb Sutter has done an extensive study on the alternatives for converting an int to a string, but I would think his arguments hold for a double as well.
He looks at the balances between safety, efficiency, code clarity and usability in templates.
Read it here: http://www.gotw.ca/publications/mill19.htm
_gcvt or _gcvt_s.
If you use the Qt4 frame work you could go :
double d = 5.5;
QString num = QString::number(d);
This is very useful thread. I use sprintf_s for it but I started to doubt if it is really faster than other ways. I came across following document on Boost website which shows performance comparison between Printf/scanf, StringStream and Boost.
Double to String is most common conversion we do in our code, so i'll stick with what i've been using. But, using Boost in other scenarios could be your deciding factor.
http://www.boost.org/doc/libs/1_58_0/doc/html/boost_lexical_cast/performance.html
In the future, you can use std::to_chars to write code like https://godbolt.org/z/cEO4Sd . Unfortunately, only VS2017 and VS2019 support part of this functionality...
#include <iostream>
#include <charconv>
#include <system_error>
#include <string_view>
#include <array>
int main()
{
std::array<char, 10> chars;
auto [parsed, error] = std::to_chars(
chars.data(),
chars.data() + chars.size(),
static_cast<double>(12345.234)
);
std::cout << std::string_view(chars.data(), parsed - chars.data());
}
For a lengthy discussion on MSVC details, see
https://www.reddit.com/r/cpp/comments/a2mpaj/how_to_use_the_newest_c_string_conversion/eazo82q/