I'm reading a text file line by line in a While loop. When I reach a specific line I want to skip the the current and the next 3 iterations.
I guess I can do it using a counter and things like that. But I was wondering if there is a more elegant way?
using (var sr = new StreamReader(source))
{
string line;
while ((line = sr.ReadLine()) != null)
{
if (line == "Section 1-1")
{
// skip the next 3 iterations (lines)
}
}
}
Have a for loop to execute sr.ReadLine 3 times and discard the result like:
using (var sr = new StreamReader(source))
{
string line;
while ((line = sr.ReadLine()) != null)
{
if (line == "Section 1-1")
{
for (int i = 0; i < 3; i++)
{
sr.ReadLine();
}
}
}
}
You should check for sr.ReadLine returning null or if the stream has come to an end.
You can use File.ReadAllLines with method extesions:
public static IEnumerable<string> SkipLines(string file, string line, int count)
{
var enumerable = File.ReadLines(file).GetEnumerator();
while (enumerable.MoveNext())
{
var currentLine = enumerable.Current;
if (currentLine == line)
{
var currentCount = 0;
while(enumerable.MoveNext() && currentCount < count)
{
currentCount += 1;
}
}
yield return currentLine;
}
}
usage:
foreach (var line in SkipLines(source, "Section 1-1", 3))
{
// your line
}
Keep in mind: ReadLines is lazy - not all lines are loaded into memory at once.
Make yourself a function that discards a given number of lines (DiscardLines) and use it:
string line;
while ((line = sr.ReadLine()) != null)
{
if (line == "Section 1-1")
{
DiscardLines(sr, 3);
}
}
That keeps the main loop very simple. The counter is now hidden in DiscardLines.
using (var sr = new StreamReader(source))
{
string line;
int linesToSkip = 0;
while ((line = sr.ReadLine()) != null)
{
if (linesToSkip > 0)
{
linesToSkip -= 1;
continue;
}
if (line == "Section 1-1")
{
// skip the next 3 iterations (lines)
linesToSkip = 3;
}
}
}
Related
In the code Below:
I read from just one text file, but i want to read from multiple files in a folder and then assign the variables and create a new instance of appointment for each file??
public bool Load()
{
DateTime start = new DateTime(2000,01,01);
int length = 0;
string screenDiscription = "";
string line;
int i = 1;
StreamReader sr = new StreamReader("Appointments.txt");
if (!File.Exists("Appointments.txt"))
{
return true;
}
while ((line = sr.ReadLine()) != null)
{
if (i % 4 == 1)
{
start = DateTime.ParseExact(line, "dd/MM/yyyy HHmm", CultureInfo.CreateSpecificCulture("en-GB"));
}
if (i % 4 == 2)
{
length = int.Parse(line);
}
if (i % 4 == 3)
{
screenDiscription = line;
apps.Add(new Appointment(start, length, screenDiscription));
}
i++;
}
sr.Close();
return true;
}
To get the all the files in a directory use the function System.IO.Directory.GetFiles("directoryPath");
Read this page for the documentation
https://msdn.microsoft.com/en-us/library/system.io.directory(v=vs.110).aspx
I'm making a function that will get the number of lines from a StreamReader excluding comments (lines which starts with '//') and new lines.
This is my code:
private int GetPatchCount(StreamReader reader)
{
int count = 0;
while (reader.Peek() >= 0)
{
string line = reader.ReadLine();
if (!String.IsNullOrEmpty(line))
{
if ((line.Length > 1) && (!line.StartsWith("//")))
{
count++;
}
}
}
return count;
}
My StreamReader's data is:
// Test comment
But I'm getting an error, 'Object reference not set to an instance of an object.' Is there any way to fix this error?
EDIT
Turns out this occurs when my StreamReader is null. So with musefan and Mr. Smith's suggested code, I came up with this:
private int GetPatchCount(StreamReader reader, int CurrentVersion)
{
int count = 0;
if (reader != null)
{
string line;
while ((line = reader.ReadLine()) != null)
if (!String.IsNullOrEmpty(line) && !line.StartsWith("//"))
count++;
}
return count;
}
Thanks for the help!
There is no need to Peek(), this may actually be the problem too. You can just do this:
string line = reader.ReadLine();
while (line != null)
{
if (!String.IsNullOrEmpty(line) && !line.StartsWith("//"))
{
count++;
}
line = reader.ReadLine();
}
Of course if you StreamReader is null then you have a problem, but you example code alone is not enough to determine this - you need to debug it. There should be plenty of debugging information for you to work out which object is actually null
Sounds like your reader object is null:
You can check if the reader is null by doing:
if (reader == null) {
reader = new StreamReader("C:\\FilePath\\File.txt");
}
Slightly neater variant of musefan's suggested code; just a single ReadLine() code. +1 for suggesting the removal of the Length check btw.
private int GetPatchCount(StreamReader reader)
{
int count = 0;
string line;
while ((line = reader.ReadLine()) != null)
if (!String.IsNullOrEmpty(line) && !line.StartsWith("//"))
count++;
return count;
}
Your code is not enough information to resolve your problem. I have made a small application with VS 2010 base on my assume and it work well. I believe your code get problem with streamReader. If the streamReader is null your code will throw 'Object reference not set to an instance of an object.'
You should check the streamReader is not null and make sure the streamReader are available.
You can reference code below. With make sure the TextFile1.txt existing at D:\
Hope this help.
namespace ConsoleApplication1
{
using System;
using System.IO;
class Program
{
static void Main(string[] args)
{
using (StreamReader streamReader = new StreamReader(#"D:\\TextFile1.txt"))
{
int count = GetPatchCount(streamReader);
Console.WriteLine("NUmber of // : {0}", count);
}
Console.ReadLine();
}
private static int GetPatchCount(StreamReader reader)
{
int count = 0;
while (reader.Peek() >= 0)
{
string line = reader.ReadLine();
if (!String.IsNullOrEmpty(line))
{
if ((line.Length > 1) && (!line.StartsWith("//")))
{
count++;
}
}
}
return count;
}
}
}
A word in this context is defined is a letter or a number. However, something like \n is not considered a word.
Below in my code I am trying to count the number of words in a file but at the for loop's local variable declaration I get the error Null Reference exception.
I am not sure why I get this error. I get the variable Line equal to null which shouldn't happen because the text file DOES have one word "hello world" in it..
StreamReader sr = new StreamReader(filePath);
while (sr.ReadLine()!=null)
{
Line =sr.ReadLine();
for (**int i = 1**; i < (Line.Length+1); i++)
{
if (Char.IsLetterOrDigit(Line[i]) == true && Char.IsLetterOrDigit(Line[i - 1]) == true)
{
if (LetterRecent == false)
{
wordCount = wordCount + 1;
}
LetterRecent = true;
}
else
{
LetterRecent = false;
}
}
}
sr.Close();
You're doing ReadLine() twice for each line.
You could do something like:
count = 0;
while (line = sr.ReadLine()) {
char oldChar = 0;
for (char c in line) {
if (c != oldChar && Char.IsLetterOrDigit(c)) count++;
oldChar = c;
}
}
You are discarding half of the lines in the file by calling sr.ReadLine() twice. If you read the last line of the file in the while statement, the call to Line.Length will throw the null reference exception.
Try something this:
var wordCount = 0;
var line = sr.ReadLine();
while( line != null ) {
for( var i = 1; i < line.Length; i++ ) {
// Count words
}
line = sr.ReadLine();
}
You need to declare wordCount before using it.
Int wordCount = 0;
while (sr.ReadLine()!=null)
{
Update your loop condition to be like this:
while (sr.Peek() >= 0)
{
Line = sr.ReadLine();
}
I want to find a string in a txt file if string compares, it should go on reading lines till another string which I'm using as parameter.
Example:
CustomerEN //search for this string
...
some text which has details about the customer
id "123456"
username "rootuser"
...
CustomerCh //get text till this string
I need the details to work with them otherwise.
I'm using linq to search for "CustomerEN" like this:
File.ReadLines(pathToTextFile).Any(line => line.Contains("CustomerEN"))
But now I'm stuck with reading lines (data) till "CustomerCh" to extract details.
If your pair of lines will only appear once in your file, you could use
File.ReadLines(pathToTextFile)
.SkipWhile(line => !line.Contains("CustomerEN"))
.Skip(1) // optional
.TakeWhile(line => !line.Contains("CustomerCh"));
If you could have multiple occurrences in one file, you're probably better off using a regular foreach loop - reading lines, keeping track of whether you're currently inside or outside a customer etc:
List<List<string>> groups = new List<List<string>>();
List<string> current = null;
foreach (var line in File.ReadAllLines(pathToFile))
{
if (line.Contains("CustomerEN") && current == null)
current = new List<string>();
else if (line.Contains("CustomerCh") && current != null)
{
groups.Add(current);
current = null;
}
if (current != null)
current.Add(line);
}
You have to use while since foreach does not know about index. Below is an example code.
int counter = 0;
string line;
Console.Write("Input your search text: ");
var text = Console.ReadLine();
System.IO.StreamReader file =
new System.IO.StreamReader("SampleInput1.txt");
while ((line = file.ReadLine()) != null)
{
if (line.Contains(text))
{
break;
}
counter++;
}
Console.WriteLine("Line number: {0}", counter);
file.Close();
Console.ReadLine();
With LINQ, you could use the SkipWhile / TakeWhile methods, like this:
var importantLines =
File.ReadLines(pathToTextFile)
.SkipWhile(line => !line.Contains("CustomerEN"))
.TakeWhile(line => !line.Contains("CustomerCh"));
If you whant only one first string, you can use simple for-loop.
var lines = File.ReadAllLines(pathToTextFile);
var firstFound = false;
for(int index = 0; index < lines.Count; index++)
{
if(!firstFound && lines[index].Contains("CustomerEN"))
{
firstFound = true;
}
if(firstFound && lines[index].Contains("CustomerCh"))
{
//do, what you want, and exit the loop
// return lines[index];
}
}
I worked a little bit the method that Rawling posted here to find more than one line in the same file until the end. This is what worked for me:
foreach (var line in File.ReadLines(pathToFile))
{
if (line.Contains("CustomerEN") && current == null)
{
current = new List<string>();
current.Add(line);
}
else if (line.Contains("CustomerEN") && current != null)
{
current.Add(line);
}
}
string s = String.Join(",", current);
MessageBox.Show(s);
Not sure if am on the right track but I want to find a index id of an array and check if it's equal to another id then display a message. it not working for some reason.
int _findID = 1;
using (StreamReader reader = new StreamReader("textfile.txt"))
{
string line = reader.ReadLine();
while (line != null)
{
string[] array = {line};
for (int i = 0; i < array.Length; i++)
{
if (array[i] == findID)
{
MesssageBox.show("Line found!!")
}
}
}
}
Any help appreciated
try
if(int.Parse(array[i]) == findID)
instead of
if (array[i] == findID)
You have to convert your string representation of your number to a int and then compare both int's.
this is even shorter than iterating over an array which always has 1 element:
while (line != null) {
if(int.Parse(array[i]) == findID)
MesssageBox.Show("Line found!!")
}
EDIT
Try
int _findID = 1;
List<String> names = new List<string>()
using (StreamReader reader = new StreamReader("textfile.txt"))
{
string line = reader.ReadLine();
int lineCount = 0;
while (line != null)
{
lineCount++;
names.Add(line);
if (lineCount == _findID)
MessageBox.Show("Line found!!");
}
}
#user1285872: array.Length this will give array length 1 in your case when you check if (array[i] == findID) thi will be (0==findID) if the value of findID ==0 then message will show.
Your code has various problems:
First if the file is not empty you have an endless loop as you read the line once and always check the same line:
string line = reader.ReadLine();
while (line != null) {}
The array is always 1 item long as you create it in the loop itself.
But for the problem with the lineID, what exactly is the content of such a line?