www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Convert strings with different format to float

reply Tom Kazimiers <2voodoo gmx.de> writes:
Hi,

I try to read data in from a file. This data consist mainly of numbers
and I have a hard time converting it to number type variables. Two data
lines could look like this

v 0 0 0
v 1.5 1.2 0

Now I want to parse those lines and call a method, the line in passed
(as char[]) to it:

int index = indexOf(line, "v ");
if(index != -1) {
    vc++;
    float x = 0.0, y = 0.0, z = 0.0;
    char[][] vertexCoords = split( line[index+2 .. $] );

    if (vertexCoords.length > 0)
        x = to!int(vertexCoords[0]);
    if (vertexCoords.length > 1)
        y = to!int(vertexCoords[1]);
    if (vertexCoords.length > 2)
        z = to!int(vertexCoords[2]);

    process_vertex(vc,x,y,z);
    return;
}

First I split the remaining characters (after "v ") into parts (here is
probably dynamic copying included?). Then I want to convert each part to
a float value.

The problem I have is that I obviously need to use "to!int" for numbers
with out decimal point and "to!float" for numbers with. But since those
can be mixed I would ask for every part if there is a decimal point, e.g:

if (vertexCoords.length > 0) {
	if (indexOf(vertexCoords[0], ".") != -1)
	        x = to!float(vertexCoords[0]);
	else
		x = to!int(vertexCoords[0]);
}

Is there a more convient way to achieve that? I am coming from C++ and
IIRC one could do there sth. like this:

int index = line.find("v ");
if(index != std::string::npos) {
    line.erase(0,index+1);
    vc++;
    float x,y,z = 0;

    std::istringstream ins;
    ins.str(line);
    ins >> x >> y >> z;

    process_vertex(vc,x,y,z);
    return;
}

That looks much cleaner to me (besides the ">>" operators). So I am
looking for sth. similar in D :-). Maybe a to!float that can cope with
numbers without decimal point.

Cheers,
Tom
Sep 08 2010
parent reply Pelle <pelle.mansson gmail.com> writes:
On 09/08/2010 09:23 AM, Tom Kazimiers wrote:
 Hi,

 I try to read data in from a file. This data consist mainly of numbers
 and I have a hard time converting it to number type variables. Two data
 lines could look like this

 v 0 0 0
 v 1.5 1.2 0

 Now I want to parse those lines and call a method, the line in passed
 (as char[]) to it:

 int index = indexOf(line, "v ");
 if(index != -1) {
      vc++;
      float x = 0.0, y = 0.0, z = 0.0;
      char[][] vertexCoords = split( line[index+2 .. $] );

      if (vertexCoords.length>  0)
          x = to!int(vertexCoords[0]);
      if (vertexCoords.length>  1)
          y = to!int(vertexCoords[1]);
      if (vertexCoords.length>  2)
          z = to!int(vertexCoords[2]);

      process_vertex(vc,x,y,z);
      return;
 }

 First I split the remaining characters (after "v ") into parts (here is
 probably dynamic copying included?). Then I want to convert each part to
 a float value.

 The problem I have is that I obviously need to use "to!int" for numbers
 with out decimal point and "to!float" for numbers with. But since those
 can be mixed I would ask for every part if there is a decimal point, e.g:

 if (vertexCoords.length>  0) {
 	if (indexOf(vertexCoords[0], ".") != -1)
 	        x = to!float(vertexCoords[0]);
 	else
 		x = to!int(vertexCoords[0]);
 }

 Is there a more convient way to achieve that? I am coming from C++ and
 IIRC one could do there sth. like this:

 int index = line.find("v ");
 if(index != std::string::npos) {
      line.erase(0,index+1);
      vc++;
      float x,y,z = 0;

      std::istringstream ins;
      ins.str(line);
      ins>>  x>>  y>>  z;

      process_vertex(vc,x,y,z);
      return;
 }

 That looks much cleaner to me (besides the ">>" operators). So I am
 looking for sth. similar in D :-). Maybe a to!float that can cope with
 numbers without decimal point.

 Cheers,
 Tom
You seem to have found a bug in to!float :-) to!float("123") works as expected, but to!float("0") bugs out. Huh!
Sep 08 2010
parent reply Don <nospam nospam.com> writes:
Pelle wrote:
 On 09/08/2010 09:23 AM, Tom Kazimiers wrote:
 Hi,

 I try to read data in from a file. This data consist mainly of numbers
 and I have a hard time converting it to number type variables. Two data
 lines could look like this

 v 0 0 0
 v 1.5 1.2 0

 Now I want to parse those lines and call a method, the line in passed
 (as char[]) to it:

 int index = indexOf(line, "v ");
 if(index != -1) {
      vc++;
      float x = 0.0, y = 0.0, z = 0.0;
      char[][] vertexCoords = split( line[index+2 .. $] );

      if (vertexCoords.length>  0)
          x = to!int(vertexCoords[0]);
      if (vertexCoords.length>  1)
          y = to!int(vertexCoords[1]);
      if (vertexCoords.length>  2)
          z = to!int(vertexCoords[2]);

      process_vertex(vc,x,y,z);
      return;
 }

 First I split the remaining characters (after "v ") into parts (here is
 probably dynamic copying included?). Then I want to convert each part to
 a float value.

 The problem I have is that I obviously need to use "to!int" for numbers
 with out decimal point and "to!float" for numbers with. But since those
 can be mixed I would ask for every part if there is a decimal point, e.g:

 if (vertexCoords.length>  0) {
     if (indexOf(vertexCoords[0], ".") != -1)
             x = to!float(vertexCoords[0]);
     else
         x = to!int(vertexCoords[0]);
 }

 Is there a more convient way to achieve that? I am coming from C++ and
 IIRC one could do there sth. like this:

 int index = line.find("v ");
 if(index != std::string::npos) {
      line.erase(0,index+1);
      vc++;
      float x,y,z = 0;

      std::istringstream ins;
      ins.str(line);
      ins>>  x>>  y>>  z;

      process_vertex(vc,x,y,z);
      return;
 }

 That looks much cleaner to me (besides the ">>" operators). So I am
 looking for sth. similar in D :-). Maybe a to!float that can cope with
 numbers without decimal point.

 Cheers,
 Tom
You seem to have found a bug in to!float :-) to!float("123") works as expected, but to!float("0") bugs out. Huh!
Yes, it's a shocking bug. It's been fixed in svn for a couple of weeks, but we haven't made a release yet.
Sep 08 2010
next sibling parent Tom Kazimiers <2voodoo gmx.de> writes:
Hi,

On 09/08/2010 05:38 PM, Don wrote:
 Pelle wrote:
 On 09/08/2010 09:23 AM, Tom Kazimiers wrote:
 [ ..]
 Maybe a to!float that can cope with
 numbers without decimal point.
You seem to have found a bug in to!float :-) to!float("123") works as expected, but to!float("0") bugs out. Huh!
Yes, it's a shocking bug. It's been fixed in svn for a couple of weeks, but we haven't made a release yet.
Great! I am looking forward to that release :-). Any idea when it will be available? For the mean time I will, as proposed, make a separate function that checks if there is a dot in it or not. Then I take to!float and to!int, respectively. Cheers, Tom
Sep 08 2010
prev sibling next sibling parent Stanislav Blinov <blinov loniir.ru> writes:
  08.09.2010 20:46, Tom Kazimiers wrote:
 Great! I am looking forward to that release :-). Any idea when it will
 be available?

 For the mean time I will, as proposed, make a separate function that
 checks if there is a dot in it or not. Then I take to!float and to!int,
 respectively.

 Cheers,
 Tom
That won't really help against this bug: to!float("0.") will also trigger assertion. You probably should just check if string contains single 0.
Sep 08 2010
prev sibling parent Tom Kazimiers <2voodoo gmx.de> writes:
On 09/08/2010 06:58 PM, Stanislav Blinov wrote:
  08.09.2010 20:46, Tom Kazimiers wrote:
 Great! I am looking forward to that release :-). Any idea when it will
 be available?

 For the mean time I will, as proposed, make a separate function that
 checks if there is a dot in it or not. Then I take to!float and to!int,
 respectively.

 Cheers,
 Tom
That won't really help against this bug: to!float("0.") will also trigger assertion. You probably should just check if string contains single 0.
Ah, thanks, I must have missed that! Regards, Tom
Sep 08 2010