Reputation: 35
I am trying to read a certain part of textfile. The text looks like the following:
[HRZones]
195
175
156
0
[SwapTimes]
[Trip]
474
0
6616
-223
[HRData]
84 182 87 -222 129 4139
84 182 87 -222 129 4139
88 179 86 -222 133 3640
95 185 92 -222 136 3393
103 193 91 -222 123 4666
107 196 94 -222 125 5684
107 198 96 -222 128 4919
109 197 95 -222 131 4926
110 198 96 -222 134 4655
111 196 95 -222 126 4154
The file actually contains a lot more lines under the [HRData] section.
I am trying to grab the [HRData} using the following code. Sadly, this locks up the program; a breakpoint shows this happens in the first while loop.. almost like it can't see anything?
private void readFile()
{
//read the hrm file and split values
try
{
using (StreamReader sr = new StreamReader(file_name))
{
string line;
while ((line = sr.ReadLine()) != "[HRData]")
{
line = sr.ReadLine(); // FAILS HERE..
}
while((line = sr.ReadLine()) != null)
{
string split = line;
string[] values = split.Split('\t');
foreach (String value in values)
{
hrdata[i, j] = int.Parse(value);
i++;
if (i > 5)
{
i = 0;
j++;
}
}
}
}
}
The file_name is being passed from a previous check and the data seems good.
Upvotes: 0
Views: 199
Reputation: 216343
With that loop you risk to jump past the line that contains your searched text because you read a line two time but test only one time
string line = sr.ReadLine();
while (line != null && line != "[HRData]")
{
line = sr.ReadLine();
}
If the file happens to have one more line before the loop probably it would have worked but the bug is still there
Upvotes: 0
Reputation: 36648
As some have already pointed out, you're reading a line during the loop condition and then again in the body of the loop so this could work or fail depending on whether [HRData]
appears on an odd or an even line of the file.
Re-write the while
loop as a for
one instead:
for (var line = sr.ReadLine();
line != null && line != "[HRData]");
line = sr.ReadLine()) { /* NOP */ }
And if you can afford to use LINQ, then the following is even simpler and doesn't require any brain gymnastics:
foreach (var line in File.ReadLines().SkipWhile(s => s != "[HRData]")) {
// ...
}
Upvotes: 1
Reputation: 4893
Check for EOF and Trim() it to make text equality to work. Following should work
while (!sr.EndOfStream)
{
var line = sr.ReadLine();
if (!string.IsNullOrWhiteSpace(line) && line.Trim() == "[HRData]")
{
break;
}
}
while (!sr.EndOfStream)
{
string split = sr.ReadLine();
string[] values = split.Split('\t');
foreach (String value in values)
{
hrdata[i, j] = int.Parse(value);
i++;
if (i > 5)
{
i = 0;
j++;
}
}
}
Upvotes: 1
Reputation: 495
2 things I noticed:
1) You have no check for the [HRData]
"tag". You check for the line not being the tag and not null.
2) I think you while loops as a whole do not know to stop reading at the end of the file.
Upvotes: 0
Reputation: 32596
Here you check one line and skip the next one. Avoid second ReadLine
.
while ((line = sr.ReadLine()) != "[HRData]")
{
line = sr.ReadLine(); // FAILS HERE..
}
Upvotes: 2