Parsing string containing doubles

  • Thread starter Thread starter Daniel =?iso-8859-1?Q?Lidstr=F6m?=
  • Start date Start date
D

Daniel =?iso-8859-1?Q?Lidstr=F6m?=

Hi,

I'm currently using this method to extract doubles from a string:

System::String* sp = S" ";
System::String* tokens[] = s->Trim()->Split(sp->ToCharArray());
m_Northing = System::Double::Parse(tokens[0], nfi);
m_Easting = System::Double::Parse(tokens[1], nfi);
m_Elevation = System::Double::Parse(tokens[2], nfi);

However, only strings that contain one " " are correctly parsed. How can I
do this for strings that contain arbitrary number of " " between doubles?
I.e.:
"79812.862 15532.942 1565.570" is ok, while
"79812.862 15532.942 1565.570" is not ok.

With C++ I would just use a stringstream. Can I do this with MC++ too? I
have not yet figure out how.

Thanks!
 
There is no real equivalent to C++'s scanf or iostreams in .NET. The thing
that comes closest to these are regular expressions (C# syntax):

using System.Text.RegularExpressions;
....
Match m = Regex.Match(yourString,
@"^\s*([0-9.,]+)\s+([0-9.,]+)\s+([0-9.,]+)\s*$");
if (m.Success)
{
Console.WriteLine(System.Double.Parse(m.Groups[1].ToString()));
Console.WriteLine(System.Double.Parse(m.Groups[2].ToString()));
Console.WriteLine(System.Double.Parse(m.Groups[3].ToString()));
}

However, Regex's are far more powerful, and it may take some time to get
used to them. It's worth the effort though, IMO.

Niki
 
Have you considered using replace to clean your string before you call
split? You could replace the " " with " ". Just a thought then you
would have to change your other code. It only requires one extra line
per type of clean up you need to do.

Wiz
 
There is no real equivalent to C++'s scanf or iostreams in .NET. The thing
that comes closest to these are regular expressions (C# syntax):

using System.Text.RegularExpressions;
...
Match m = Regex.Match(yourString,
@"^\s*([0-9.,]+)\s+([0-9.,]+)\s+([0-9.,]+)\s*$");
if (m.Success)
{
Console.WriteLine(System.Double.Parse(m.Groups[1].ToString()));
Console.WriteLine(System.Double.Parse(m.Groups[2].ToString()));
Console.WriteLine(System.Double.Parse(m.Groups[3].ToString()));
}

However, Regex's are far more powerful, and it may take some time to get
used to them. It's worth the effort though, IMO.

How would I write this in MC++? I tried this but got compilation errors:

#using <System.dll>

using namespace System::Text::RegularExpressions;
....
Match* m = Regex::Match(s,
"^\\s*([0-9.,]+)\\s+([0-9.,]+)\\s+([0-9.,]+)\\s*$");
if( m->Success ){
m_Northing = System::Double::Parse(m->Groups->Item(1)->ToString());
m_Easting = System::Double::Parse(m->Groups->Item(2)->ToString());
m_Elevation = System::Double::Parse(m->Groups->Item(3)->ToString());
}

(113) : error C2064: term does not evaluate to a function taking 1
arguments
(113) : error C2227: left of '->ToString' must point to class/struct/union

113 refers to m_Northing = ... line. Also, is the regular expression
written to be equivalent with the CS example? What does the @ at the start
of the CS RE mean?
Thanks!

--
Daniel
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
 
Daniel Lidström said:
...
How would I write this in MC++? I tried this but got compilation errors:
...

Item is an indexer; Try:
m_Northing = System::Double::Parse(m->Groups->Item[1]->ToString());
m_Easting = System::Double::Parse(m->Groups->Item[2]->ToString());
m_Elevation = System::Double::Parse(m->Groups->Item[3]->ToString());
Also, is the regular expression
written to be equivalent with the CS example?

Yes, I think so.
What does the @ at the start of the CS RE mean?

In a "normal" C# string you have to escape backslashes like in C. However if
you prefix the string literal with @, you can put in backslashes like any
other character. Nice feature for paths or regular expressions.
Maybe you should have a look at a tool like Expresso
(http://www12.brinkster.com/ultrapico/Expresso.htm). It's perfect for
testing a regular expression on sample data, and it can create correct MC++
code (with correctly escaped backslashes).

Just curious: why do you use MC++? I tend to use C# where I can, because I
don't like all those special keywords like "__gc", "__value" and so on.

Niki
 
This small chunk of code will do what you are looking for Niki.


string t = " some string with odd number of spaces";
int i = t.IndexOf(" ",0);
int j = t.IndexOf(" ",0);
while( i > 0 || j > 0)
{
t = t.Replace(" "," ");
i = t.IndexOf(" ",0);
j = t.IndexOf(" ",0);
}

Hope that helps

-Wiz
 
Back
Top