Jump to content
dummzeuch

converting float to text

Recommended Posts

I'm mostly a Delphi programmer, I have no experience with C++ (or Java or C#) and only used C many (>20) years ago, so please forgive me if I ask stupid  questions. I am currently struggling to write some C++ code to use a 3rd party library that's written in C++.

 

Given a buffer pointed to by zMap containing float values, how do I convert these values to strings?

 

I know that these values are between 1 and 3 with the odd inf sprinkled in, because I have dumped the memory to a file and read it in Delphi as Single.

(And also because these values are supposed to be a distance in that range.)

 

This is what I tried to output the first value:

  float* zMap = SomeFunctionThatReturnsABuffer();
  char buffer[100];
  snprintf(buffer, sizeof(buffer), "%f", *zMap);
  cout << buffer << " " << endl;

I got a large number (>1000), even though I know that the values are between 1 and 3.

 

If I use the same code on an array like this:

  float Arr[3] = {1.1, 2.1, 2.5};
  float* Ptr = Arr;
  char buffer[100];
  snprintf(buffer, sizeof(buffer), "%f", *Ptr);
  cout << buffer << " " << endl;

It works as expected.

What am I missing here?

Share this post


Link to post

The '%f' specifier in ...printf() style functions expects 'double' (or 'long double' if you use '%Lf'), not 'float'.  There is no specifier that accepts 'float'.  So, you will have to cast the values when passing them in, eg:

snprintf(buffer, sizeof(buffer), "%f", (double) *zMap); // or: double(*zMap), or static_cast<double>(*zMap)

Alternatively, you can format the 'float' to a C++ 'std::string' first, and then copy it into your buffer, eg:

std::ostringstream oss;
oss << *zMap;
strncpy(buffer, oss.str().c_str(), sizeof(buffer)-1);

Or:

strncpy(buffer, std::format("{}", *zMap).c_str(), sizeof(buffer)-1);

Of course, being a Delphi guy, you could just use the Delphi RTL in C++Builder to convert the 'float' to a 'System::String' first, and then copy it into your buffer, eg:

strncpy(buffer, AnsiString(FloatToStr(*zMap)).c_str(), sizeof(buffer)-1);
// or simpler:
strncpy(buffer, AnsiString(*zMap).c_str(), sizeof(buffer)-1);

Or, simply get rid of the buffer altogether and use the 'std::string'/'System::(Ansi)String' as-is instead.

 

That being said, your two examples are logically equivalent, so if the above approaches don't fix the issue, then make sure the pointer being returned by SomeFunctionThatReturnsABuffer() is actually valid to begin with (ie, that the memory buffer is not being freed before you copy the data, etc).

Edited by Remy Lebeau
  • Thanks 1

Share this post


Link to post
On 6/30/2023 at 6:04 PM, dummzeuch said:

I know that these values are between 1 and 3 with the odd inf sprinkled in, because I have dumped the memory to a file and read it in Delphi as Single.

(And also because these values are supposed to be a distance in that range.)

Turns out I didn't check carefully enough. There actually are values in that array that are much too large, and these values show up in the Delphi dump as well.

 

So: There was nothing wrong with the C++ code, just me being stupid.

Sorry about that.

 

I still have no idea where these values come from. Maybe the algorithm that calculates them is flawed.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×