Click here to Skip to main content
15,891,597 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
Hello all,

I am fairly new to C#. I come from a C/C++ world. I am working on a project that I need to parse a text file that contains data logging. Each new data that is logged is time stamped. I need to find a specific date and time stamp. Then at that point, start reading the data (saving it off to another temp.txt file), line by line until I come to an end date/time stamp. Then done.

Example:
user inputs (via the GUI) start time of Sun Jan 30 01:20:00 2011.
Then they enter a end time of Mon Jan 31 10:20:06 2011
Then I will have a "go button" that then has the program parse the entire file for the start date/time stamp and begin writing a new temp file with the data from this point on until end time is found.
The catch here is that the user will not know the exact time to start/end. So I am having them put in the hour:min and no seconds. So I would assume my code would search for only the string
Sun Jan 30 01:07: 2011. (note no seconds shown)
In the "C" world I would create a while or for loop. But I have read in the C# world there are easier ways to parse a file?
And of course I would need to put in some error trapping such that if the ented dates do not match any strings in the file then I set the user know.

..... remember I don't know C#, this is just an example I came up with. Can you give me a snippet that will do what I want?
thanks!

using (StreamReader mystr = new StreamReader("datafile.txt")) 
{
   while (true)
    {
        datalines = mystr.ReadLine();
        if (datalines == startdate)
            break; # found the start point
        else
            
            continue;
    }
  
    
    while ((datalines = mystr.ReadLine()) != endDate)
    {
        #write the line out to a temp file
    }
}
mystr.close


[edit]Code block added to preserve formatting - OriginalGriff[/edit]
Posted
Updated 28-Feb-11 8:44am
v2

There is a much simpler way: no loops required:
C#
string startdate = "Sun Jan 30 01:20:00 2011";
string enddate = "Mon Jan 31 10:20:06 2011";
string content = File.ReadAllText(@"F:\Temp\justsometext.txt");
int start = content.IndexOf(startdate);
if (start >= 0)
    {
    start += startdate.Length;
    int end = content.IndexOf(enddate, start);
    if (end >= 0)
        {
        string log = content.Substring(start, end - start);
        Console.WriteLine(log);
        }
    }

[edit]JSOP very correctly pointed out a bug: fixed - OriginalGriff[/edit]
 
Share this answer
 
v2
Comments
#realJSOP 28-Feb-11 15:02pm    
It looks like yor code will stop at the first instance of the end date, and will ignore any log entries that occur in the same minute after the first instance.
OriginalGriff 28-Feb-11 15:10pm    
I never said it was perfect! :laugh:
You are right, it would be much better to start searching from the end of the start sequence - fixed.
Davidscott59 28-Feb-11 17:18pm    
I should clarify, here that my data log could have thousands of lines in it. Is it a good idea to read the entire file into a string??
ALso.... I tried you snippet of code. It does not work. the int variable start always returns a -1 at the content.Indexof() return
OriginalGriff 1-Mar-11 3:18am    
It works if the start date is in the file: otherwise the IndexOf returns -1
I.e.: it works here exactly as is, with a file I created to dummy the data you have.
Perhaps if you post a small fragment of your actual data it would help?
Davidscott59 28-Feb-11 16:47pm    
OK. so this just looks like c++ coding. I thought there was some fancy c# way to do this using streamreader and regex.ismatch or some other fancy way. (see my attempt later in the thread) But hey! if simple works, then great! I will try your snippet and let you know how it worked. Thanks.
You're going to have to retrieve the date/time from each log entry to do what you want. I wrote a tip/trick that makes it easy to compare two DateTime objects for just the parts you care about:

Partial DateTime Object Equality[^]
 
Share this answer
 
Comments
Davidscott59 28-Feb-11 16:37pm    
I'm not sure I follow your code. Seems more complicated than I would expect for my application.
#realJSOP 28-Feb-11 18:22pm    
Well, you need to parse each string to extract the date, and then convert that date to a DateTime object. Once you get it there, you want compare things down to the min, and leave seconds/milliseconds out of it. The code in that tip/trick will allow you to do just that. You can set a global variable for the comparison flags, and just use it over and over again. The rest of the code is merely extension methods for the DateTime object. Look at it this way, the work is done. All you have to do is copy/paste the code from the tip to your own project, and Bob's your uncle.
Davidscott59 28-Feb-11 18:57pm    
I don't think I need to treat it like a DateTime Object. These are just log files I am parsing, and I am searching for a string. It just happens that the string is in the format of a date and time. And yes, I would need to get right down to the second because the data logger is recording in the format of HH:mm:ss. so I would have to find the last second ( up to 59) of the string I am searching for. The snippet of code I put in here for solution 3 works, but it does not consider what would happen if there was an end time within the 60 seconds of my time, since I am only looking at HH:MM.(reason is the user may not know the seconds) My code also does not trap if it can't find either the start or stop time strings in the search. I need to figure out how to do these three things tasks.. But maybe I am missing something in my thinking logic. I will dissect your code and see if it will work for me....
#realJSOP 1-Mar-11 8:57am    
Well, according to your orginal question (at least the way I understood it), you need to find all log entries between a certain date/time, but you only need to find them for a certain minute (or range of minutes). There's no way to compare datetimes in string format - you HAVE to parse the string, and then convert the date/time part to a datetime object, just so you can compare the dates/times. Since you're only comparing down to the minute (for example, you want all log entries for 01/01/2011 at 12:05), you need a way to tell your comparer code what to compare. That's what my code does. I noticed that your log entry examples don't show a second/millisecond for the entry's date/time, and if that's the case, you don't really need the cited code because when you parse the string into a date time, the second/millisecond will both default to 0. However, if the log entries do in fact retain the second/millisecond, you will need to consider that. Lastly, I'm not saying that you need to use the cited code - I merely suggested it as a way to speed your development along.I've used it in a number of projects, so I know it works for the intended purpose.
OK... so I just wrote a small test app in C# to fiddle around with this.
It works, but probably not graceful. and like John said above, my end point would not take into consideration any lines that occur in the same minute before the next minute. So I need to fix that.
here is the snippet. I would appreciate any feedback.

private void button1_Click(object sender, EventArgs e)
        {
            string dataRow = "";
            string startdate = "Feb 5 01:10:";
            string enddate = "Feb 5 04:15:";

            try
            {
                TextReader tread = new StreamReader("acutemp.log");
                TextWriter twrite = new StreamWriter("newtemp.txt");

                while (true)
                {
                    dataRow = tread.ReadLine(); // read each line of the file
                    if (dataRow.Contains(startdate))
                        break;
                    else
                        //
                        continue;
                }
                while ((dataRow = tread.ReadLine()) != null)
                {
                    twrite.WriteLine(dataRow); // write the lines from start to end dates

                    if (dataRow.Contains(enddate)) // if found the end date then exit loop
                        break;
                }


                tread.Close();
                twrite.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }


[edit]Code block added to preserve formatting - OriginalGriff[/edit]
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900