1

I have a following question, as I am just starting to learn C#.

I have a class defined like this:

public class Piksel
    {
        public int r;
        public int g;
        public int b;
    }

I then declare an array like so:

Piksel[,] tab2 = new Piksel[32, 32];

Now, I have a *.txt file in the following format:

...

X: 15 , Y: 2 , R: 255 , G: 255 , B: 255

X: 16 , Y: 2 , R: 183 , G: 183 , B: 183

X: 17 , Y: 2 , R: 32 , G: 32 , B: 32

X: 18 , Y: 2 , R: 32 , G: 32 , B: 32

X: 19 , Y: 2 , R: 159 , G: 159 , B: 159

X: 20 , Y: 2 , R: 255 , G: 255 , B: 255

...

I load it into a richTextBox:

 OpenFileDialog openF1 = new OpenFileDialog();
        openF1.InitialDirectory = "C:\\Users\\Nagash\\Desktop";
        openF1.Title = "Wybierz plik z danymi obrazka";
        openF1.DefaultExt = "*txt";
        openF1.Filter = "Pliki TXT|*txt";

        if (openF1.ShowDialog() == System.Windows.Forms.DialogResult.OK && openF1.FileName.Length > 0)
        {
            richTextBox3.LoadFile(openF1.FileName,RichTextBoxStreamType.PlainText);
        }

And now my question: how can I put that data in the tab2 array from the richTextBox. For example, if a line in richTextBox reads

X: 15 , Y: 2 , R: 255 , G: 255 , B: 255

then what i want is the following result:

tab2[15,2].r=255 tab[15,2].g=255 tab[15,2].b=255

I treid fiddling with regular expressions like so:

MatchCollection mc = Regex.Matches(richTextBox3.Text, "[0-9]+");
        foreach (Match str in mc)
            richTextBox1.Text= richTextBox1.Text + Convert.ToString(str);

But then I am unsure how to tell if a number is 255 or is it 25 and a 5. Also still unsure how to put it into the array.

Thanks for help.

2 Answers 2

1

I am not sure what you win from loading the text into a textbox, but whereever you take the text from that you want to process, you are probably best off if you do the processing in a series of steps:

First, Split the text into rows (since seemingly one row corresponds to one pixel)

var rows = text.Split("\r\n"); // Or only \r, whatever fits

Then, Parse each row and create an intermediate object of the form { int X; int Y; int R; int G; int B; }. Or you use a dictionary for each row.

var inputs = rows.Select(r => Parse(r));

Finally, Iterate through the newly created objects and process each.

foreach (var input in inputs)
{
    Piksel[input['X'], input['Y']] = new Piksel { r = input['R'], g = input['G'], b = input['B'] };
}

This boils your question down to as how to parse a line of the following form

X: 15 , Y: 2 , R: 255 , G: 255 , B: 255

into a dictionary with values for each X, Y, R, G, and B. This can be the proper place to apply regular expressions. Or you use Split again:

private Dictionary<string, int> Parse(string row)
{
    var keysAndValues= row.Split(',');
    var dict = new Dictionary<string, int>();

    foreach (var keyValue in keysAndValues)
    {
        var parts = value.Split(':');
        var key = parts[0];
        var value = int.Parse(parts[1]);

        dict[key] = value;
    }

    return dict;
}
Sign up to request clarification or add additional context in comments.

4 Comments

Hey, thanks for the great explanation. I don't "win" anything by putting that text in the rTB, it's just a program I do for my class, and one of the requirements is loading txt file into rTB, so i tohught why not do it while doing other thing already. I don't really understand your code now yet, but will read on the commands you used. Thanks again.
@user3706568 - Got it.
Just one question, what is r in your code, a variable? And if so, which one?
@NagashTDN: r => Parse(r) is a lambda. It defines a function with one parameter named r which is a short for "row". The type string is automatically deduced because you execute Select on a collection of strings. Select iterates through the string array (that is, through the rows of the text), and for each row it calls Parse, passing the row as the argument.
0

Hi you can just save your file like this :

15 , 2 , 255 , 255 , 255

and use this function to separate the values:

  static  IEnumerable<string> LineSplitter(string line)
        {
            int fieldStart = 0;
            for (int i = 0; i < line.Length; i++)
            {
                if (line[i] == ',')
                {
                    yield return line.Substring(fieldStart, i - fieldStart);
                    fieldStart = i + 1;
                }
                if (line[i] == '"')
                    for (i++; line[i] != '"'; i++) { }
            }

        }

And to convert these values to an array use this :

 IEnumerable<string>  res= LineSplitter(theString);
                  string[] array = res.Cast<string>().ToArray();

It's an example you should change it .

I hope this helps.

3 Comments

Hello, thanks for answer. However, I need my text file to be in that exact format, wtih the letters and ":". Is there any way to rewrite the function you provided to include that formatting?
Yes, as you can see every char in the string is checked ,you can rewrite it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.