简体   繁体   中英

C# parsing a Vector2 from string

I am trying to load a Vector2 into my game by reading it from a text file as a string and then parsing it. But when I try to load this info, I get this exception:

Format exception was unhandled. Input string was not in a correct format.

Text file:

{X:512 Y:384}

Code:

System.IO.StreamReader objReader;
objReader = new System.IO.StreamReader(@fileName + ".txt");

string pos = objReader.ReadLine();

float aXPosition = float.Parse(pos.Substring(pos.IndexOf("X:"), pos.IndexOf(" Y")));
float aYPosition = float.Parse(pos.Substring(pos.IndexOf("Y:"), pos.IndexOf("}")));

So what I'm trying to do is reading the X and Y position from the text file. I found this technique here: http://social.msdn.microsoft.com/Forums/sk/xnagamestudioexpress/thread/fd94cfec-f1f4-4cab-aa1d-8c72b524875b

Looks pretty simple, but for some reason it's not working for me. Any help would be much appreciated!

I think you should just use XmlSerializer instead, it will be a lot less work.

For example:

class MySaveGame
{
    public Vector2 Point1 { get; set; }
    public Vector2 Point2 { get; set; }
}

To Save:

XmlSerializer serializer = new XmlSerializer(typeof(MySaveGame));
using (var stream = File.Create(@"C:\yourpath.xml"))
{
    serializer.Serialize(stream, new MySaveGame { Point1 = new Vector2(3, 3) });
}

To Read:

using (var stream = File.OpenRead(@"C:\yourpath.xml"))
{
    var mySave = serializer.Deserialize(stream) as MySaveGame;
}

That was off the top of my head, double check my code

It's probably because IndexOf gives you index of X in X: you've specified in parameter. Try something like this:

System.IO.StreamReader objReader;
objReader = new System.IO.StreamReader(@fileName + ".txt");

string pos = objReader.ReadLine();

int startInd = pos.IndexOf("X:") + 2;
float aXPosition = float.Parse(pos.Substring(startInd, pos.IndexOf(" Y") - startInd));
startInd = pos.IndexOf("Y:") + 2;
float aYPosition = float.Parse(pos.Substring(startInd, pos.IndexOf("}") - startInd));

Update

I've tested the code and there was also an issue with count parameter of Substring method. It should indicate length of the substring and not the end index in the original string. I updated the code, so it should work correctly now.

Format exception was unhandled. Input string was not in a correct format.

You are getting this exception because you are trying to parse a string which is not a string representation of a float.

The String.Substring MSND documentation says:

Retrieves a substring from this instance. The substring starts at a specified character position and has a specified length.

The second parameter is the length of the string you want to extract not the index where to stop the extraction and that explains your issues.

In fact:

Given this string {X:512 Y:384} , pos.IndexOf("X:") = 1, pos.IndexOf(" Y") = 6

=> pos.Substring(pos.IndexOf("X:"), pos.IndexOf(" Y"))

=> pos.Substring(1 , 6)

=> X:512 and this is not a float!

Back to the solution to your problem:

  1. Clean the string from all non numeric characters (leave the blank space in between)
  2. The resulting string should now only contain the values you want and a space in between
  3. Split your string. You now have an array with 2 strings containing the values your want, just parse them.

Here is a sample code for doing this:

                                               //"{X:512 Y:384}"
String cleanString = pos.Replace("{X:", "");   //"512 Y:384}"
cleanString = cleanString .Replace("Y:", "");  //"512 384}"
cleanString = cleanString .Replace("}", "");   //"512 384"
String[] xyVals = cleanString.Split(' ');      //"512" and "384"
float aXPosition = float.Parse(xyVals[0]);
float aYPosition = float.Parse(xyVals[1]);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM