Convert float to std::string in C++
Unless you're worried about performance, use string streams:
#include <sstream>
//..
std::ostringstream ss;
ss << myFloat;
std::string s(ss.str());
If you're okay with Boost, lexical_cast<> is a convenient alternative:
std::string s = boost::lexical_cast<std::string>(myFloat);
Efficient alternatives are e.g. FastFormat or simply the C-style functions.
How to simply convert a float to a string in c?
The second parameter is the format string after which the format arguments follow:
fprintf(fPointer, "%f", amount);
%f
tells fprintf
to write this argument (amount
) as string representation of the float value.
A list of possible format specifiers can (for example) be found here.
Convert float to std::string without losing precision. Also I don't want to use sprintf
I suggest you call snprintf
with format specifier "%.16g"
- that prints a double
in decimal with 16 significant digits of precision. See Number of Digits Required For Round-Trip Conversions for more details. E.g.:
inline std::string as_string(double value) {
char buf[32];
return std::string(buf, std::snprintf(buf, sizeof buf, "%.16g", value));
}
*printf
functions are fundamental conversion routines, everything else uses these.
std::to_string
in GNU C++ standard library does:
inline string to_string(double __val) {
const int __n = __gnu_cxx::__numeric_traits<double>::__max_exponent10 + 20;
return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, __n, "%f", __val);
}
std::ostream
also calls *snprintf
under the hood to format numbers.
Also note that 3.14159267
is double
. A float
constant requires f
suffix, e.g. 3.14159267f
.
How to speed up this code when converting float to string?
If using an external library to achieve this goal is possible, you can go with fmtlib (this library will probably make it into the standard), which claims to be faster than other approaches (see their benchmarks).
#include <fmt/format.h>
std::string FloatToScientificString(float val, int width, int precision)
{
return fmt::format("{:>{}.{}e}", val, width, precision);
}
This should return an identical string as your original function, and you don't sacrifice type safety as with std::*printf
approaches. When using abseil instead (they claim to be notably faster than the printf
-family here), the function looks like this:
#include <absl/strings/str_format.h>
std::string FloatToScientificString(float val, int width, int precision)
{
return absl::StrFormat("%*.*e", width, precision, val);
}
There is also boost format, which does not allow for width or precision specifier to be passed as arguments, but this works equally well:
#include <boost/format.hpp>
std::string FloatToScientificString(float val, int width, int precision)
{
const std::string fmt = "%" + std::to_string(width) + "." +
std::to_string(precision) + "e";
return boost::str(boost::format(fmt) % val);
}
and finally, without any external dependencies other than the standard library (note that using std::snprintf
is superior to std::sprintf
as the buffer size is checked, but neither function is type safe):
#include <cstdio>
std::string FloatToScientificString(float val, int width, int precision)
{
static const int bufSize = 100;
static char buffer[bufSize];
std::snprintf(buffer, bufSize, "%*.*e", width, precision, val);
return std::string(buffer);
}
A correct performance analysis of these options is probably a topic on its own. Any of these options should be notably faster than the original approach using std::stringstream
, though, and all snippets except the std::snprintf
one are type safe.
Convert float to string with precision & number of decimal digits specified?
A typical way would be to use stringstream
:
#include <iomanip>
#include <sstream>
double pi = 3.14159265359;
std::stringstream stream;
stream << std::fixed << std::setprecision(2) << pi;
std::string s = stream.str();
See fixed
Use fixed floating-point notation
Sets the
floatfield
format flag for the str stream tofixed
.When
floatfield
is set tofixed
, floating-point values are written using fixed-point notation: the value is represented with exactly as many digits in the decimal part as specified by the precision field (precision
) and with no exponent part.
and setprecision.
For conversions of technical purpose, like storing data in XML or JSON file, C++17 defines to_chars family of functions.
Assuming a compliant compiler (which we lack at the time of writing),
something like this can be considered:
#include <array>
#include <charconv>
double pi = 3.14159265359;
std::array<char, 128> buffer;
auto [ptr, ec] = std::to_chars(buffer.data(), buffer.data() + buffer.size(), pi,
std::chars_format::fixed, 2);
if (ec == std::errc{}) {
std::string s(buffer.data(), ptr);
// ....
}
else {
// error handling
}
I have an issue converting a float variable into a string in C++
strlen()
is for calculating length of C-style string.
To obtain the length of std::string
, you should use the size()
or length()
member function.
cout<<threshold.length()<<endl;
In case you want to stick to use strlen()
, you can use c_str()
member function to obtain C-style string from std::string
.
cout<<strlen(threshold.c_str())<<endl;
Converting a float to string in a subroutine in C
You're trying to use sprintf
to write data to a char
. Look at the declaration of the sprintf
function, as your compiler suggests:
int sprintf(char*, const char*, ...)
It takes a char*
as first argument, that is: a pointer to a buffer where to store the formatted string that is generated.
You should use it like this (please pay attention to all the changes I made):
// Return the allocated buffer, which is char*, not char.
char *test_subroutine(float x,float y)
{
float a=105.252342562324;
float b=108.252234256262;
float d;
float e;
char *var = malloc(100); // Allocate a buffer of the needed size.
d=x*a;
e=y*b;
sprintf(var,"%0.2f %0.2f",d,e); // Sprintf to that buffer
return var;
}
int main()
{
char *variable;
variable = test_subroutine(2.5,3.5);
free(variable); // Free the buffer allocated by test_subroutine()
}
C++ How do I format a float with std::string?
Found a way using stringstream :) Then it uses the default ostream float format and pushes it to a string :)
std::stringstream ss;
std::string s;
ss << 3.4;
ss >> s;
std::cout << s.append("f") << std::endl;
generates the following output:
3.4f
Convert float to string with precision and without tolerance
The problem is that you're using a float
data type which only has a precision of at most 7.22 total digits and sometimes as little as 6 digits, and you're trying to display 8 total digits (2 before the decimal and 6 after). As noted in the comments, the closest possible binary float to 40.432 is 40.43199920654296875, the second closest would be 40.432003021240234375.
You can get more digits by converting to the larger double
type. Once you've done that you can round to the nearest 6-digit number. Note that if the float
was generated by a calculation, rounding may actually create a less accurate result.
If you always know your numbers will be between 10 and 100, this simple code will work. Otherwise you'll need a more complex process to determine the appropriate amount of rounding.
float f = 40.432;
double d = f;
double r = std::round(d * 10000.0) / 10000.0; // 2 digits before the decimal, 4 after
std::cout << std::fixed << std::setprecision(6) << r;
Note that the last 2 digits will always be zero because of the rounding.
See it in action: http://coliru.stacked-crooked.com/a/f085e56c03ebeb73
Related Topics
Is There Any Standard Way of Embedding Resources into Linux Executable Image
With a Private Modifier, Why Can the Member in Other Objects Be Accessed Directly
How to Target Windows Xp in Microsoft Visual Studio C++
Why Is There No Support for Concatenating Std::String and Std::String_View
Why Was the Space Character Not Chosen for C++14 Digit Separators
How to Atomically Update a Maximum Value
Why Is My Object Not Being Copied When Move Constructor Is Deleted
Pointer Interconvertibility VS Having the Same Address
Std::Unique_Ptr, Deleters and the Win32 API
Is There Support in C++/Stl for Sorting Objects by Attribute
Is There Any Way a C/C++ Program Can Crash Before Main()
Get Current Time in Milliseconds Using C++ and Boost
Is "Inline" Implicit in C++ Member Functions Defined in Class Definition
What Is an Iterator in General
C++ Automatic Factory Registration of Derived Types
Why Explicitly Delete the Constructor Instead of Making It Private