0

I have these text files as structured:

value1 value2 value3          
Table1 Table2 Table3
(data set values here)
.
.
.(represent text in between)
.
value1 value2 value3
Table1 Table2 Table3            
(data set values here)          

and

value1 value2 value3          
Table1 Table2 Table3
(data set values here)
.
.
.(represent text in between)
.
value1 value2 value3
Table1 Table2 Table3            
(data set values here)
.
.
. 
value1 value2 value3
Table1 Table2 Table3            
(data set values here)

As they are here, they are structured differently, with some having two Table sets, some having three, and others having 4. However, they all share a common characteristic that that they all have the same formatting of how the table is structured:

value1 value2 value3
Table1 Table2 Table3            
(data set values here)   

What I want to do is that I want to be able to skip to the last occurrence of each data set at the bottom, regardless of the number of lines in the file, which is the one shown above. How would I be able to detect the last values at the vary end?

What I have so far is:

string[] lines = File.ReadAllLines("myTextfile.txt"); //stores text file in array
foreach(var item in lines)
{
    Console.WriteLine(item.ToString()); //foreach loop here prints out code to console, line by line

}

I think I would have to use the LastIndexOf Method, then specify those values in the parameters, then use it in conjunction with the for loop but I am unsure how to implement it so it would detect it.

EDIT

Input of sample text files:

Time: 5:30am         
EndTime: 5:30pm.
.
.(represent text in between)
.
Time: 7:30am         
EndTime: 8:30pm           

Time: 6:30am         
EndTime: 1:30pm 
.
.
.(represent text in between)
.
Time: 8:30am         
EndTime: 9:30pm
.
.
. 
Time: 3:30am         
EndTime: 4:30pm

What I want to be able to is detect the last occurence of Time and EndTime, so when the program is run it will return:

//for the first one 
Time: 7:30am         
EndTime: 8:30pm 
//for the second one 
Time: 3:30am         
EndTime: 4:30pm
  • 1
    The generality of your question makes it hard to comprehend, could you give 2 different examples of input files and the expected/requested output? – Lasse V. Karlsen Jun 12 '20 at 18:04
  • Question: What if the first file there contains one line at the start with `Time: 5:30am`, then `. . (represent text in between) . . ` and then followed by `EndTime: 8:30pm`, would you like the `Time` line + the `EndTime` line? What I mean to ask is if there will always be a pairt of `Time`/`EndTime` lines together, or if you really want "the last Time" followed by "the last EndTime"? – Lasse V. Karlsen Jun 12 '20 at 18:22
  • 1
    Your question could be answered simply with `var time = ""; var endTime = ""; foreach (string line in File.ReadAllLines("filename.text")) { if (line.StartsWith("Time:")) time = line; else if (line.StartsWith("EndTime:")) endTime = line; } Console.WriteLine(time); Console.WriteLine(endTime);`, please tell me what is wrong with this solution and then we're getting somewhere. – Lasse V. Karlsen Jun 12 '20 at 18:24
  • I see what you mean, i think what I mean is that I want the "the last Time" then followed by "the last EndTime", as i want them in two seperate occurences. – thesenate42069 Jun 12 '20 at 18:24
  • Oh I see, it is looping through all the Time, EndTime variables, then once it reaches the end it sets it to those values – thesenate42069 Jun 12 '20 at 18:34
  • 1
    Does the code in my comment above actually produce what you want? – Lasse V. Karlsen Jun 12 '20 at 18:35
  • Yes it works, I just have play around with it for a bit, thank you! – thesenate42069 Jun 12 '20 at 18:37

2 Answers2

2

The simplest way to do the following:

  • Gather the last occurance of a line starting with "Time:"
  • Gather the last occurance of a line starting with "EndLine:"
  • Output the two as "Time: xxx" followed by "EndTime: xxx", with those two lines

would be something like this:

string time = "";
string endTime = "";
foreach (string line in File.ReadLines("filename.txt")) // or any source of strings
    if (line.StartsWith("Time:"))
        time = line;
    else if (line.StartsWith("EndTime:"))
        endTime = line;
// error handling would go here, like what if time is still empty? or endTime?
Console.WriteLine(time);
Console.WriteLine(endTime);
Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
0

I'd build off the reading end of file question/answers on SO. So you could read a small buffer of lines to get the end ones. Something like this:

    static async Task Main(string[] args)
    {
        using (var reader = new StreamReader("foo.txt"))
        {
            var (start, end) = DecomposeLastTwoTimeLines(reader);

            Console.WriteLine($"Start: {start}");
            Console.WriteLine($"End: {end}");
        }
    }

    static ValueTuple<string, string> DecomposeLastTwoTimeLines(StreamReader reader)
    {
        long TimeLinesLength = ("EndTime: 12:30pm".Length * 2 * 2) + 2;

        if (reader.BaseStream.Length > TimeLinesLength)
        {
            reader.BaseStream.Seek(-TimeLinesLength, SeekOrigin.End);
        }

        List<string> lines = new List<string>();

        string line;
        while ((line = reader.ReadLine()) != null)
            lines.Add(line);

        if (lines.Count < 2)
            throw new FileFormatException();

        return (lines[^2], lines[^1]);
    }
MikeJ
  • 1,299
  • 7
  • 10