Hello, I need some help from you guys - thing is:

I've got a text file with numbers, it looks like this:

X, Y, Z.
X and Y are float type, the Y is an integer. The file has many lines.

How do I load that file, seperating X and Y, from Z, into 2 arrays - 1 array for X and Y, second for Z?

Secondly, once I've loaded those, and done some math on the numbers, I'd like to draw coordinate axes, and that data (which is points - x and y). How do I do that?

My attempt to read, load into string and parse into float, failed :/

string text = System.IO.File.ReadAllText("my-path-to-file");
            string[] texts = text.Split(',');
            float[] in = new float[texts.Length];
            for (int i = 0; i < texts.Length; i++)
            {
                in[i] = float.Parse(texts[i]);

Dani AI

Generated

Short summary and a safe, practical pattern you can apply now.

As pointed out, read the file line-by-line rather than reading the whole file into one giant string. Use a per-line loop, Split(',') and use TryParse so a single bad line does not throw exceptions. File.ReadLines is a convenient way to iterate lines lazily. (learn.microsoft.com)

Practical parsing example (robust to blanks, extra spaces and locale differences):

using System.Globalization;
using System.IO;
using System.Linq;
using System.Collections.Generic;

struct Point2 { public float X; public float Y; }

var points = new List<Point2>();
var labels = new List<int>();

foreach (var line in File.ReadLines("file.txt"))
{
    if (string.IsNullOrWhiteSpace(line)) continue;
    var parts = line.Split(',');
    if (parts.Length < 3) continue;

    if (!float.TryParse(parts[0].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out float x)) continue;
    if (!float.TryParse(parts[1].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out float y)) continue;
    if (!int.TryParse(parts[2].Trim(), out int z)) continue;

    points.Add(new Point2 { X = x, Y = y });
    labels.Add(z);
}

Use the TryParse overloads with NumberStyles and an IFormatProvider to avoid problems with decimal separators and to keep parsing predictable. (learn.microsoft.com)

If you specifically want two arrays (one for X/Y pairs, one for Z), convert the lists when ready:

float[] xs = points.Select(p => p.X).ToArray();
float[] ys = points.Select(p => p.Y).ToArray();
int[] zs   = labels.ToArray();

For drawing on WinForms: handle plotting in OnPaint (use the provided Graphics object), compute min/max, compute scale factors, map world coords to pixel coords (px = margin + (x-minX)sx; py = height-margin - (y-minY)sy), draw axes with DrawLine and draw points with FillEllipse. System.Drawing.Graphics provides the drawing primitives you need. (learn.microsoft.com)

If you prefer not to hand-roll axes and scaling, plot libraries save a lot of pain—ScottPlot (easy WinForms/WPF usage) and OxyPlot (cross-platform) are good modern choices. already suggested graph libraries; ScottPlot and OxyPlot are maintained options to consider. (scottplot.net)

Small troubleshooting notes: define structs/classes outside methods (that was the cause of the "while in class" errors you saw; explained this). Trim parts, skip malformed lines or log them, and prefer TryParse over Parse for cleaner code.

Recommended Answers

All 13 Replies

Check StreamReader class please.

Following code piece is taken exactly from above page :P, I am too lazy to type of my own nor do I have my VM up :(

using System;
using System.IO;

class Test 
{
    public static void Main() 
    {
        try 
        {
            // Create an instance of StreamReader to read from a file.
            // The using statement also closes the StreamReader.
            using (StreamReader sr = new StreamReader("TestFile.txt")) 
            {
                string line;
                // Read and display lines from the file until the end of 
                // the file is reached.
                while ((line = sr.ReadLine()) != null) 
                {
                    Console.WriteLine(line);
                }
            }
        }
        catch (Exception e) 
        {
            // Let the user know what went wrong.
            Console.WriteLine("The file could not be read:");
            Console.WriteLine(e.Message);
        }
    }
}

Now where

Console.WriteLine(line);

is used you can use the read line as follows:

string[] texts = line.Split(',');

Please mark the issue as resolved if it helps.

Umm, the whole point is to get the numbers from file into an array in float type, so I can perform some math operations on the array values. Loading into string is not good, sorry if I missed that in my 1st post.

X and Y are float type, the Y is an integer.

What is Z? Float?

I didn't add that part because you had already done that there.

struct Vertices
{
    public float X;
    public float Y;
    public int Z;
}

....

List<Vertices> vertList = new List<Vertices>();
//...
//...
while ((line = sr.ReadLine()) != null)
{
    string[] texts = line.Split(',');
    Vertices vert = new Vertices();
    vert.X = int.Parse(texts[0]);
    vert.Y = int.Parse(texts[1]);
    vert.Z = float.Parse(texts[2]);
    vertList.Add(vert);
}
//...
//...

....

foreach(Vertices vert in vertList)
{
    //Do anything you want with vert. :)
}

Correction below:

List<Vertices> vertList = new List<Vertices>();
//...
//...
while ((line = sr.ReadLine()) != null)
{
    string[] texts = line.Split(',');
    Vertices vert = new Vertices();
    vert.X = float.Parse(texts[0]);
    vert.Y = float.Parse(texts[1]);
    vert.Z = int.Parse(texts[2]);
    vertList.Add(vert);
}
//...
//...

: yep, Z is int, sorry for the typo

: thanks, although I have no idea on how those collection-thingys work; gonna read up;
Still remains the graphic part, you wouldn't happen to have a full perceptron code? With reading in/out from files, computing weights, and drawing pretty pictures of 2 sets of points separated with a line, in coordinate axes? Sorry for my bad "math english" :/

Though interesting, I would let the urge to subside to go to that length :)
As for a bit more info, you can check this
Hope that helps :D

Instead of using float.Parse (or int.Parse) please use TryParse. If something cannot be parsed using the former method, an exception is thrown. Which means you need to put all your Parsing into a try/catch block.

However, TryParse simply returns false if it cannot be parsed making for much tidier code and leaving out an unnecessary try/catch block.

The signature for TryParse is Boolean Int32.TryParse(String toParse, out Int32 result); Same applies for Single, Double, Int64 etc. (Single is the C# object type for float, Int32 is int and Int64 is long)

Argh, result's kinda the same: can't parse to float, I get 26 errors. With the code:

using System;
using System.IO;
using System.Collections.Generic;


public class Blah
    {
        static void Main()
        {
            
            struct dane{
                public float X;
                public float Y;
                public int Z;
            }

        string line;
        StreamReader sr = new StreamReader("file.txt");
        List<data> dataList = new List<data>();
        while ((line = sr.ReadLine()) != NULL)
        {
         string[] texts = line.Split(',');
         data dat = new data();
         dat.X = float.Parse(texts[0]);
         dat.Y = float.Parse(texts[1]);
         dat.Z = float.Parse(texts[2]);
         dataList.Add(dat);
        }

Invalid token 'while' in class, struct, or interface member declaration - I get this at "while", then at "=", then some more at "()", and at other places.
A field initializer cannot reference the non-static field, method, or property - at line.Split.
Array size cannot be specified in a variable declaration (try initializing with a 'new' expression) - at texts[0].

You've attempted to declare your struct inside a method. This is invalid. You need to remove the struct definition to inside the class, but outside the method.

Well it doesn't even need to be in the class really you can have it outside also.

Also, your struct is called dane and you're referencing it as data (unless you have another struct somewhere called data but I can't see one from your code)

There's another error in there also that I haven't mentioned. But it should be obvious once you fix the rest of it.

I leave it to you as an exercise :)

Ok, got it, thanks. I assume the one you didn't mention is type mismatch (int<->float, weird though, that a language won't allow me to do that, even if it's "wrong").

Any graphics-pro here to help with the drawing part?

In the case of C# it's not so weird if you understand what goes on beneath the hood.

A much simplified explanation is that what you're actually doing is returning an object which is a reference type. Although there is a conversion, you have to explicitly cast it, like you would in C++. It's not returning the number, say for example, 24 (which is a value type). It's returning an int (or Int32 which is what it translates to).

Actually it might be better to show you in code form:

From your code above what you're asking it to do is this.

{
    /* Some code here */
    MyClass myClass = new MyClass();
    MyClassTwo anotherClass = MyClassTwo();
    myClass = anotherClass; // Obviously you can't do this. They aren't the same object.
    // The same applies with the int/float/double types.
    // I'll use the C# object version to help highlight the difference
    Int32 myInt = new Int32();
    myInt = 20; // Valid
    myInt = 20.4; // Not valid, this is a double. But it lets you know you can cast it.
    myInt = (Int32)20.4; // Valid with precision warning.
    myInt = new Double(); // Not valid. Different Objects.
    Double myDouble = new Double();
    myDouble = 20.4; // Valid
    myInt = myDouble; // Not Valid. Same as above.
    myInt = (Int32)myDouble; // Valid. But with precision error.
}

Hope that helps explain it for you =)


As for the drawing, there is a graph control somewhere on the net and you just feed it the points you want to draw. I've used it before, but I can't remember. Give me 5 minutes to find it.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.