-1

I'm new to C#. I'm trying to write a winforms application that reads a text file and prints the specific lines according to the conditions. For example, I have a text file look like this:

07/10 08:15:00 EVENT: IN
07/10 08:15:00 BUILDING: A
07/10 08:15:00 ROOM: 101
07/10 08:15:00 MEMBER: JOHN, MARIA, PETER, SOPHIA
07/10 08:15:00 --------------------------------------
07/11 17:15:00 EVENT: OUT
07/11 17:15:00 BUILDING: B
07/11 17:15:00 ROOM: 102
07/11 17:15:00 MEMBER: ANDY, HAN, CINDY, LESTER
07/11 17:15:00 --------------------------------------
07/12 09:30:00 EVENT: IN
07/12 09:30:00 BUILDING: A
07/12 09:30:00 ROOM: 101
07/12 09:30:00 MEMBER: JIMMY, NICKY, EMILY, DANIEL
07/12 09:30:00 --------------------------------------
07/13 08:46:00 EVENT: IN
07/13 08:46:00 BUILDING: B
07/13 08:46:00 ROOM: 202
07/13 08:46:00 MEMBER: ROMEO, JULIET, WILLIAM
07/13 08:46:00 --------------------------------------
07/13 15:29:00 EVENT: IN
07/13 15:29:00 BUILDING: A
07/13 15:29:00 ROOM: 101
07/13 15:29:00 MEMBER: THOMAS, VIVIAN, KIM, SAMUEL
07/13 15:29:00 --------------------------------------
07/14 20:33:00 EVENT: OUT
07/14 20:33:00 BUILDING: A
07/14 20:33:00 ROOM: 301
07/14 20:33:00 MEMBER: JIMMY, NICKY, DANIEL
07/14 20:33:00 --------------------------------------

I want to print the event name and all other lines belong to this event when it match all 3 conditions as below:

  • Condition1: Event: IN
  • Condition2: Building: A
  • Condition3: Room: 101

Result should be like this:

07/10 08:15:00 EVENT: IN
07/10 08:15:00 BUILDING: A
07/10 08:15:00 ROOM: 101
07/10 08:15:00 MEMBER: JOHN, MARIA, PETER, SOPHIA
07/10 08:15:00 --------------------------------------
07/12 09:30:00 EVENT: IN
07/12 09:30:00 BUILDING: A
07/12 09:30:00 ROOM: 101
07/12 09:30:00 MEMBER: JIMMY, NICKY, EMILY, DANIEL
07/12 09:30:00 --------------------------------------
07/15 10:11:00 EVENT: IN
07/15 10:11:00 BUILDING: A
07/15 10:11:00 ROOM: 101
07/15 10:11:00 MEMBER: THOMAS, VIVIAN, KIM, SAMUEL
07/15 10:11:00 --------------------------------------

Here is my code:

private void btnSearch_Click(object sender, EventArgs e)
    {
        txtResult.Clear();
        int counter = 0;
        string line;
        if (txtPath.Text != "")
        {
            StreamReader reader = new StreamReader(txtPath.Text);
            while ((line = reader.ReadLine()) != null)
            {
                if (line.Contains("EVENT: IN"))
                {
                    //problem at this line
                    txtResult.Text += line + "\r\n";
                    if ((line = reader.ReadLine()) != null)
                    {
                        if (line.Contains("BUILDING: A"))
                        {
                            txtResult.Text += line + "\r\n";
                            if ((line = reader.ReadLine()) != null)
                            {
                                if (line.Contains("ROOM: 101"))
                                {
                                    txtResult.Text += line + "\r\n";
                                    if ((line = reader.ReadLine()) != null)
                                        txtResult.Text += line + "\r\n";
                                    if ((line = reader.ReadLine()) != null)
                                        txtResult.Text += line + "\r\n";
                                }
                            }
                        }
                    }
                }
                counter++;
            }
            reader.Close();
        }
        else
            MessageBox.Show("Find not found!", "Message", MessageBoxButtons.OK);
    }

The problem is when it reach the first condition, it prints all the lines that contain the word 'EVENT: IN', like this:

07/10 08:15:00 EVENT: IN
07/10 08:15:00 BUILDING: A
07/10 08:15:00 ROOM: 101
07/10 08:15:00 MEMBER: JOHN, MARIA, PETER, SOPHIA
07/10 08:15:00 --------------------------------------
07/12 09:30:00 EVENT: IN
07/12 09:30:00 BUILDING: A
07/12 09:30:00 ROOM: 101
07/12 09:30:00 MEMBER: JIMMY, NICKY, EMILY, DANIEL
07/12 09:30:00 --------------------------------------
07/13 08:46:00 EVENT: IN
07/13 15:29:00 EVENT: IN
07/15 10:11:00 EVENT: IN
07/15 10:11:00 BUILDING: A
07/15 10:11:00 ROOM: 101
07/15 10:11:00 MEMBER: DONALD, GARETH, BOBBY
07/15 10:11:00 --------------------------------------

My question is how to print only lines that match all 3 conditions?

Thank for help!

Lee
  • 11
  • 3
  • 1
    It's because you're telling it to write out that line if it only matches that first condition. You need to be reading all lines for each grouping *and then* conditionally check their values. You could create a custom class for events and store those rather than working with individual lines of text and it'll probably be much easier to work with (and more maintainable IMO) – Broots Waymb Jul 19 '21 at 16:17
  • Side note: the members in your 3rd group (DONALD, GARETH, BOBBY) do not exist in the source file you've posted. It seems that they should be "THOMAS, VIVIAN, KIM, SAMUEL" – Broots Waymb Jul 19 '21 at 16:30
  • Yes, you're right. I typed wrong. The members in 3rd group exactly are "THOMAS, VIVIAN, KIM, SAMUEL". – Lee Jul 19 '21 at 16:43

1 Answers1

1

This is one simple way to do it. I just whipped this up in a console app, so you can replace the calls to Console.WriteLine in order to write to your TextBox. It's not exactly the "best" solution, but since you're essentially needing to write a simple parser, it should get you started.

string file = @"<path to your file>";

string[] lines = File.ReadAllLines(file);

//Check the file in blocks of 5 lines, from the "EVENT" line through the "-------" line
//Assumes file structure is always consistent
for (int i = 0; i < lines.Length; i += 5)
{
    string eventLine = lines[i];
    string buildingLine = lines[i + 1];
    string roomLine = lines[i + 2];

    if (eventLine.EndsWith("EVENT: IN") &&
        buildingLine.EndsWith("BUILDING: A") &&
        roomLine.EndsWith("ROOM: 101"))
    {
        Console.WriteLine(lines[i]);     //EVENT: IN
        Console.WriteLine(lines[i + 1]); //BUILDING: A
        Console.WriteLine(lines[i + 2]); //ROOM: 101
        Console.WriteLine(lines[i + 3]); //MEMBER: <list of members>
        Console.WriteLine(lines[i + 4]); //-------------------------
    }
}
Broots Waymb
  • 4,713
  • 3
  • 28
  • 51
  • Yes, it's work. Thank you! Maybe I should learn more about 'custom class'. – Lee Jul 19 '21 at 17:08
  • @Lee - Here are some good official resources on the topic: https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/types/classes and https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/tutorials/classes – Broots Waymb Jul 19 '21 at 17:14
  • Thank you. I have one more question. If I expand the problem like add more events with more/less than 5 lines, this way won't work correctly. Is there any other way to handle that? – Lee Jul 19 '21 at 17:56
  • @Lee - You'll basically use the "-------" line to delimit your groupings. So start reading line by line as in this example, then after you read the "-------" line you'll know that your next line starts a new event group. Adding something like `while (!line.EndsWith("------"))` should work. Of course, you'll need to tweak other things as well, but it shouldn't be too hard. – Broots Waymb Jul 19 '21 at 18:05