Parsing Float From Table Gives Error

Hello,

I’m having an issue parsing floats

string[] readText = File.ReadAllLines("Assets/DataCSV/Characters.csv");
        for (int i = 0; i < readText.Length; ++i)
        {
            string[] values = readText[i].Split(',');
            for (int j = 0; j < values.Length; ++j)
            {

                CharacterDesignData characterDesignData = new CharacterDesignData();
                characterDesignData.m_ID = Animator.StringToHash(values[0]);
                characterDesignData.m_Name = values[1];
                characterDesignData.m_Exp = float.Parse(values[2]);
                // characterDesignData.m_Level = float.Parse(elements[3]);

It works fine until I bring in floats.

FormatException: Input string was not in a correct format.
System.Number.ThrowOverflowOrFormatException (System.Boolean overflow, System.String overflowResourceKey) (at <8ce0bd04a7a04b4b9395538239d3fdd8>:0)
System.Number.ParseSingle (System.ReadOnlySpan`1[T] value, System.Globalization.NumberStyles styles, System.Globalization.NumberFormatInfo info) (at <8ce0bd04a7a04b4b9395538239d3fdd8>:0)
System.Single.Parse (System.String s) (at <8ce0bd04a7a04b4b9395538239d3fdd8>:0)
CharacterInfoViewParser.ParseCharacters () (at Assets/Scripts/Editor/Parser/CharacterParser.cs:33)

Looking at other threads it might be a culture issue, but from what I can tell, the language/keyboard on my machine is set to English US keyboard.

I’m relatively new to C# so Id appreciate any help on a fix.

Thanks

Unless I miss my guess your issue has nothing to do with nearly 90% of you code. You haven’t shown any part of the .csv file BTW.

Can you eliminate reading the file, simply assign a representative value and see the error?

Thanks for reply.

I did this in CharacterData.cs

public class CharacterData
{
    public int m_ID;
    public string m_Name;
    //points
    public float m_Exp;

    public void SomeMethod()
    {
        m_Exp = 25;
    }

// the rest removed for readability

}

This does not give errors, and shows log


static void ParseCharacters()
    {
        string filePath = Application.dataPath + "/DesignDataCSV/Characters.csv";
        if (!File.Exists(filePath))
        {
            Debug.LogError("Missing Data: " + filePath);
            return;
        }

        string[] readText = File.ReadAllLines("Assets/DesignDataCSV/Characters.csv");
        for (int i = 0; i < readText.Length; ++i)
        {
            string[] values = readText[i].Split(',');
            for (int j = 0; j < values.Length; ++j)
            {

                CharacterData characterData = new CharacterData();
                characterData.SomeMethod();
                Debug.Log(characterData.m_Exp);
            }
             
        }
    }
}

I’m building this off of tutorials trying to learn some of the ins and outs of the language, so the .csv is very much bare bones in excel.

image

If the issue is how the code is written perhaps it gets addressed further in the tutorial.

Parsing string data into integers / floats, etc.

If you have a string such as “123” and want to turn it into an integer or float using int.Parse(); or int.TryParse();, then that string must be absolutely sanitized spotlessly clean.

This means that the string cannot have ANY other non-numeric characters in it, such as spaces or even newlines. Even a blank string with nothing is typically considered invalid.

Unfortunately both spaces and newlines are invisible when printed out in the console.

To see such things, always put brackets around in your Debug.Log() statements, like so:

Debug.Log("[" + TheStringIWantToParse + "]);

Another way is to iterate all the characters with a for() loop and spit them out one at a time and see if there are any that don’t even show up in the log at all:

for (int i = 0; i < TheStringIWantToParse.Length; i++)
{
	int c = TheStringIWantToParse[i];

	Debug.Log("Character at position " + i + " is ASCII " + c);
}

Whatever your issue ends up being, you may need to manipulate the string to remove the illegal character(s). Look up any good C# tutorial on string manipulation for how to do this step, which will be completely dependent on what your actual illegal characters are.

I tried this within the existing loop, but using

int c = values[j]

gives error

Cannot implicitly convert type 'string' to 'int':

so I tried this:

  string c = values[j];
Debug.Log("Character at position " + j + " is ASCII " + c);
Character at position 2 is ASCII 150
UnityEngine.Debug:Log (object)
CharacterInfoViewParser:ParseCharacters () (at Assets/Scripts/Editor/Parser/CharacterParser.cs:33)

150 is the exp float that fails. Does this mean anything?

I also opened the .csv as a .txt file, and all the fields were separated by commas. no white space/tabs.

Your values is a string array, not a string.

Extract the string you’re working on (probably values[2] in your original code, line 11… what line did the original error happen on? That’s important!!) and check that string’s characters. Yes, it looks like 150 but there might be more in there.

I was thinking more about constructing the array without reading the file. Parsing a single float wouldn’t be an issue.

Clearly a bit of debugging is called for but what I would do in the interest of time is to try changing the value in that cell. I would edit it and test. I would copy one that worked and test. I’d swap the rows and test. I might skip over that cell and test.

If it can parse everything except for that cell it points to something amiss with that cell’s value. If it can’t parse 150 no matter where you place it that indicates that there is something amiss with the number 150 (which there won’t be).

In the interest of time, OP should have noted which line is blowing up.

We still don’t know for sure but we can infer it was values[1]

But did OP chop off the left edge of the table snipp[et and is actually trying to parse Mage or Knight or even Exp perhaps?

Never try to parse Mages. Or Knights. Or Wizards, I suppose.

                characterDesignData.SomeMethod();
                Debug.Log(characterDesignData.m_Exp);
                Debug.Log(characterDesignData.m_Level);
                // float testfloat = (float)characterDesignData.
                float testfloat = 122.22f;
                Debug.Log(testfloat);

Works as expected

I tried a few variations. I’ve tried swapping the values in the .csv, I’ve tried swapping values in the loops.
I tried disabling values of strings/hash that come before it.

The result is the same. Once it hits a float, any float, it gives an error.

On top of all that,

I tried copying to google sheets. I tried downloading both csv, and tsv. tried using \t to split.

Same result.

So I just used

Animator.StringToHash(values[2]);

for all the floats.

Debug.Log(values[j]);

shows all correct values.

I have no clue if this is good or bad but at the moment it doesn’t matter

The top line in your CSV file is the text headers.

Those will never parse as any float.

Your code starts parsing at that line (where your for() loop starts i = 0).

This means your code will attempt to parse text headers into floats.

Again, if that’s what is happening, that will never work.

Do you actually intend to be parsing lines 1 onwards?

Again, debugging, debugging, debugging. Find out what is happening.

Yes that was the cause. I didn’t even consider it.

for (int i = 1; i < readText.Length; ++i)

Starting my loop at 1 instead of 0 fixed the issue. Good to know going forward.

Thanks for the help.

1 Like

Just so you know, that’s how it almost ALWAYS works. Honest. Even for veterans.

Debug, debug, debug, and you will go through these six steps:

One must work through the six stages of debugging:

  • DENIAL. That can’t happen.
  • FRUSTRATION. That doesn’t happen on my machine.
  • DISBELIEF. That shouldn’t happen.
  • TESTING. Why does that happen?
  • GOTCHA. Oh, I see.
  • RELIEF. How did that ever work?

You may laugh now, but it will really seem hilarious to you after the 1000th time it happens.

Remember: the code DOES NOT MATTER. Look at the data. Debugging lets you look at the data.

1 Like