David Bentley
David Bentley

Reputation: 864

Code to search text file for exact string and performing action if found is failing

So, I wrote some code that is suppose to read a text file and then check for an instance of a specific string. If that string exists it will need to perform an action. I have added some message boxes to let me know the progress of the function. The problem is, it is not finding the word. Here is my code:

private void test2_Click(object sender, EventArgs e)
{
    StreamReader objReader = new StreamReader("C:\\testing\\mslogon.log");
    string sLine = "";
    ArrayList arrText = new ArrayList();
    MessageBox.Show("File Read");

    while (sLine != null)
    {
        sLine = objReader.ReadLine();
        if (sLine != null)
        {
            arrText.Add(sLine);
        }
    }

    if (arrText.Contains("Invalid"))
    {
        MessageBox.Show("Word Invalid Found");
    }
    else
    {
        MessageBox.Show("Nada");
    }
}

Upvotes: 2

Views: 558

Answers (6)

Jim Mischel
Jim Mischel

Reputation: 134035

Your code is doing way too much work. If all you want to know is whether the file contains any line with the word "Invalid" in it, you don't have to read the whole file at once. And you can stop at the first line you find. Consider this:

bool found = false;
var lines = File.ReadLines(@"c:\testing\mslogon.log");
foreach (var sLine in lines)
{
    if (sLine.IndexOf("Invalid") != -1)
    {
        found = true;
        break;
    }
}
if (found)
{
    MessageBox.Show("Found it!");
}
else
{
    MessageBox.Show("Not found.");
}

And, you can replace that foreach with a LINQ expression:

bool found = lines.Where(sLine => sLine.IndexOf("Invalid") != -1).Any();

The key here is that File.ReadLines creates an enumerator that lets you read the file one line at a time, rather than loading the entire file into memory. In the loop, the break terminates the loop early if a line is found. In the LINQ expression, the Any method does essentially the same thing. The point being that if "Invalid" is found on the first line, there's no need to read through the rest of the file.

Upvotes: 1

Gustavo F
Gustavo F

Reputation: 2206

You have to search in every item of array, in your actual code, only a string with the exact content "Invalid" will work.

Using LINQ, you can do this:

    if (arrText
        .ToArray()
        .Where(p => ((string)p).Contains("Invalid")).Any())
    {
        MessageBox.Show("Word Invalid Found");
    }

Upvotes: 0

rory.ap
rory.ap

Reputation: 35318

The problem is that by doing arrText.Contains("Invalid"), you're searching each element of the array for "Invalid", so unless you have a single line in your text file with that text, it won't be found.

You need to search each line as you're building the array, and set your flag there.

var isFound = false;
var searchPhrase = "Invalid";

while (sLine != null)
{
    sLine = objReader.ReadLine();
    if (sLine != null)
    {
        arrText.Add(sLine);
        if (sLine.Contains(searchPhrase)) isFound = true;
    }
}

if (isFound)
{
    MessageBox.Show("Word Invalid Found");
}
else
{
    MessageBox.Show("Nada");
}

Upvotes: 2

JokerManh
JokerManh

Reputation: 34

try this:

private void test2_Click(object sender, EventArgs e)
{
    StreamReader objReader = new StreamReader("C:\\testing\\mslogon.log");
    string sLine = "";
    ArrayList arrText = new ArrayList();
    MessageBox.Show("File Read");

    while (sLine != null)
    {
        sLine = objReader.ReadLine();
        if (sLine != null)
        {
            arrText.Add(sLine);
        }
    }
    foreach(string x in arrText)
    {
      if (x.Contains("Word Invalid Found"))
      {
        MessageBox.Show("Nothing Found");
      }
      else
      {
        MessageBox.Show("Nada");
      }
    }
}

Upvotes: 2

Alexei - check Codidact
Alexei - check Codidact

Reputation: 23078

If your file is not very big, consider reading all text at once using File.ReadAllText function.

Also, by default, search is done in a case sensitive manner, so you will miss "word invalid found".

Upvotes: 1

DWright
DWright

Reputation: 9500

Right now, you are checking arrText for an element that is exactly equal to "Invalid". If "Invalid" is embedded in some larger string, it will not find it.

To check whether any of the strings contain Invalid, you'd have to do:

foreach(var line in arrText)
{
    if (line.Contains("Invalid")) { MessageBox.Show("Word 'Invalid' Found"); break; }
}

Using File.ReadAllText as @Alexei mentions would enable you to do something you are wanting to do and would look something like this:

String wholeFile = File.ReadAllText();
if (wholeFile.Contains("Invalid")) { 
    MessageBox.Show("Word 'Invalid' Found"); 
} else {
. . .

Upvotes: 3

Related Questions