Convert strings with different format to float

Stanislav Blinov stanislav.blinov at gmail.com
Wed Sep 8 01:02:34 PDT 2010


Jonathan M Davis wrote:
> On Wednesday 08 September 2010 00:23:31 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
> 
> I would have thought that to!float() could handle a number without a decimal 
> point. If it can't I would suggest creating a bug report for it. Now, since such 
> a fix would not help you immediately in either case, I would suggest creating a 
> wrapper function which took a string and then used to!int() for numbers without 
> decimal points and to!float() for number with them, and then returned a float. 
> That way, you wouldn't have to keep worrying about it. Also, you could try 
> parse(). It might be more forgiving.
> 
> - Jonathan M Davis

No it wouldn't :)
It's indeed a bug, and it happens if string contains e.g. single 0 
(other digits are parsed normally). It seems that parse for floating 
points tries to determine if the number is in hex format, thus eating 
first 0, but it does not reuse this 0 later while it tries to pop next 
characters (and that results in assertion in std.array).


More information about the Digitalmars-d-learn mailing list