I have code that generates a string (which is held in a variable). I need to compare this string to see if it matches any one of many strings contained in a txt file. I am not sure how to do this. I have read a bit about steamreader, which may be a viable method.

Also, should I import all the data from the text file into a database within the program - would this increase the efficiency of the program in terms of access speed?

I have not yet created the textfile from which I want to import. The separator I would use would be return, as opposed to comma.

From what I have read, one must start by instantiating str (or equivalent:

StreamReader str = new StreamReader("c:\\sample.txt");

But I am not sure where to go from there...

Thanks in Advanced,

Dan.

Recommended Answers

All 20 Replies

First lemme say,So far so good. Whether or not you need a DB for this application depends on its complexity. If this is just a little thing, I wouldn't bother, but if this a full scale, or extremely complex situation, then look to a database.

To check and see if the two string matches you could do something like this(I wrote this example in C++, but you could do this in C#):

/*** Comparing two strings ***/
#include <iostream>

using namespace std;

int main()
{
    string a="Hello";
    string b="wasup";

    if(b == a)
    {
        cout << "they are the same";
    }
    else {cout << "they are different";}

    return 0;
}

hope i helped :)

First lemme say,So far so good. Whether or not you need a DB for this application depends on its complexity. If this is just a little thing, I wouldn't bother, but if this a full scale, or extremely complex situation, then look to a database.

To check and see if the two string matches you could do something like this(I wrote this example in C++, but you could do this in C#):

/*** Comparing two strings ***/
#include <iostream>

using namespace std;

int main()
{
    string a="Hello";
    string b="wasup";

    if(b == a)
    {
        cout << "they are the same";
    }
    else {cout << "they are different";}

    return 0;
}

hope i helped :)

Thanks for the quick reply. The comparison of strings is not so much the issue... it's more the importing.

wooops....sorry :icon_redface:

Importing a string shouldn't be to hard....maybe get a class to open a file, read a line, save it to an array, etc. and then just compare it like i did above

I'm guessing you already know all this stuff, but:
http://www.devhood.com/Tutorials/tutorial_details.aspx?tutorial_id=400

Like I've said, I'm a C++ kind of guy...so if I'm not making a lot of sense, bear with me lol

i didnt understand why you respond to c# question with c++?

i didnt understand why you respond to c# question with c++?

i thought i was in the C++ forum lol:icon_redface: ....

I have code that generates a string (which is held in a variable). I need to compare this string to see if it matches any one of many strings contained in a txt file. I am not sure how to do this. I have read a bit about steamreader, which may be a viable method.

Also, should I import all the data from the text file into a database within the program - would this increase the efficiency of the program in terms of access speed?

I have not yet created the textfile from which I want to import. The separator I would use would be return, as opposed to comma.

From what I have read, one must start by instantiating str (or equivalent:

StreamReader str = new StreamReader("c:\\sample.txt");

But I am not sure where to go from there...

Thanks in Advanced,

Dan.

you can use either regular expressions or built in string functions like string.Compare or string.Contains or string.indexOf

you can use either regular expressions or built in string functions like string.Compare or string.Contains or string.indexOf

As I said, the issue isn't comparing the strings, it is the importing of the text file.

An update, I now have this:

try
            {


                List<string> list = new List<string>();
                using (StreamReader reader = new StreamReader("C:\\Users\\Dan\\Documents\\words.txt"))
                {
                    string line;
                    while ((line = reader.ReadLine()) != null)
                    {
                        list.Add(line);
                       
                    }
                }


                
            }
            catch (Exception e)
            {
                Console.WriteLine("The file could not be read:");
                Console.WriteLine(e.Message);
            }



            bool valid = false;
            for (int i = 0; i < 2; i++)
            {
                if (word == list[i])
                {
                    valid = true;
                    if (!(lstList.Items.Contains(word)))
                    {
                        lstList.Items.Add(word);
                    }
                }
            }

but get an error saying the name 'list' doesn't exist in the current context. Obviously, there is a different way to access this particular variable due to it's irregular instantiation:
List<string> list = new List<string>();
That is, I have never seen anything instantiated like that before (I am of course a beginner).

So how do I access "list"??

at what line you get that error?

I've changed it again sorry... posting on the go. I am almost done now I think, I have this (for the whole method), it compiles correctly but doesn't seem to work:

bool testifvalid(string word)
        {

            bool valid = false;

            try
            {


                List<string> list = new List<string>();
                using (StreamReader reader = new StreamReader("C:\\Users\\Dan\\Documents\\words.txt"))
                {
                    string line;
                    while ((line = reader.ReadLine()) != null)
                    {
                        list.Add(line);
                        
                        for (int i = 0; i < 1; i++)
                        {
                            if (word == list[i])
                            {
                                valid = true;
                                if (!(lstList.Items.Contains(word)))
                                {
                                    lstList.Items.Add(word);
                                }
                            }
                        }
                    }
                }


                
            }
            catch (Exception e)
            {
                // Let the user know what went wrong.
                Console.WriteLine("The file could not be read:");
                Console.WriteLine(e.Message);
            }


            return valid;
        }

UPDATE: Yes, I can see why it doesn't work I think. I am calling this function a lot - as in, to be precise 33554432 times which means it is reading the file that many times... I'll have to find a way to pass in "list"

the first thing i noticed, your for loop is wrong you want it to loop between 0 and 1 which means it cant loop

i dont know what exactly you are trying to do but if you are searching text file for some text do the following :

StreamReader testTxt = new StreamReader(fName);
            string allRead = testTxt.ReadToEnd();//Reads the whole text file to the end

then use indexOf method to search for a string, allRead.indexOf("yourtext"), this will return the index, or you can use Contains..

Ok. This is now a matter of efficiency. I have the following code:

bool testifvalid(string word)
        {

            bool valid = false;
            bool alreadydone = true;

         
            try
            {
                if (list[0] == null) { alreadydone = false; }
                if (alreadydone == false)
                {
                    int counter = 0;
                    using (StreamReader reader = new StreamReader("C:\\Users\\Dan\\Documents\\words.txt"))
                    {
                        string line;
                        while ((line = reader.ReadLine()) != null)
                        {
                            list[counter] = line;
                            counter += 1;
                            numwords = counter;
                        }
                        
                    }
                }


                        for (int i = 0; i < numwords; i++)
                        {
                            if (word == list[i])
                            {
                                valid = true;
                                if (!(lstList.Items.Contains(word)))
                                {
                                    lstList.Items.Add(word);
                                }
                            }
                        }
                    
                


                
            }
            catch (Exception e)
            {
                Console.WriteLine("The file could not be read:");
                Console.WriteLine(e.Message);
            }


            return valid;
        }

I am fairly sure it works. However, as we speak my program is running (and has been for a while now) using all possible resources... Due to the number of times the procedure is called, it will take a while.

So then, would your suggested method be more efficient in terms of time than mine do you think?

as long as you get it done, dont worry about efficiency in the beginning level. programming is about work arounds for the most time(i hope Narue dont see this and come to prove me wrong).
now what is your problem again?

Some remarks :
>Your coding style seems rather chaotic, to say the least.

>Why do you test if you want to continue with your function INSIDE the function? Never call a function if it is not needed. Your alreadydone variable should be used outside the function. Btw. the for loop always gets called so it would crash your program if list is null. Ignoring the catch, which in this case would give a wrong message.

> Try to use code tags when you post code.

>I'm inferring from your last code that you have a file which contains only words. So why don't you follow the suggestion of serkan given in post #13?

Can you do something like:

private void button3_Click(object sender, EventArgs e)
    {
      const string word = @"hello";
      string[] lines = System.IO.File.ReadAllLines(@"C:\File.txt");
      foreach (string s in lines)
      {
        string[] lineWords = System.Text.RegularExpressions.Regex.Split(s, @"\W+");
        for (int i1 = 0; i1 < lineWords.Length; i1++)
        {
          if (string.Compare(lineWords[i1], word, true) == 0)
          {
            //You found the data
          }
        }
      }
    }

making separate list seems to be more efficient. I have split it into two functions and tried two different methods:

Method 1:

void LoadWords()
{
StreamReader testTxt = new StreamReader("C:\\Users\\Dan\\Documents\\words.txt");
allRead = testTxt.ReadToEnd();
}

void testifvalid (int numletters, string word)
{

if (allRead.Contains(word))
{
       if (!(lstList.Items.Contains(word)))
       {
        lstList.Items.Add(word);                    
       }
}

}

Method 2:

void testifvalid(int numletters,string word)
        {


         SetRange(ref starpos, ref endpos, word);
            

            for (int i = starpos; i < endpos; i++)
            {
                
               
                

                if (word == list[word.Length,i])
                {
                   if (!(lstList.Items.Contains(word)))
                    {
                        lstList.Items.Add(word);
                        break;
                    }
                }
            }
                    


        }

        void LoadWords()
        {

            try
            {
                    
                    using (StreamReader reader = new StreamReader("C:\\Users\\Dan\\Documents\\words.txt"))
                    {
                        string line;
                        //while the line is not blank
                        while ((line = reader.ReadLine()) != null)
                        {
                            //add that line to the list array, the first element being the length of the word
                            //and the second the "counter", incremented everytime a word is added.
                            list[line.Length,numwords[line.Length]] = line;
           
                            int temp = ConverttoInt(line);

                            //sets an index for where a letter starts i.e. 0 is start of a,
                            //3000 is starts of b, etc.
                            if (startof[line.Length, temp] == 0)
                            {
                                startof[line.Length, temp] = numwords[line.Length];
                            }
                                numwords[line.Length] += 1;
    
                        }


                    //  }

                    //    sw.Close();
                    //  }

                        
                }

                   
            }
            catch (Exception e)
            {
                MessageBox.Show("Unable to set start positions");
                MessageBox.Show(e.Message);
            }
             
        }

The latter is a lot faster. I don't know whether I could incorporate sknake's suggestion...

So let me get this straight .. you have a single string in a variable and you want to see if it exists in a given text file? What is this about counting how many times the word was used?

Here:

using System;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace daniweb
{
  public partial class frmRegex : Form
  {
    public frmRegex()
    {
      InitializeComponent();
    }
    private void button1_Click(object sender, EventArgs e)
    {
      //To prove the regex works
      TestRegex();

      //Now to really match
      const string fName = @"C:\test.txt";
      const string myWord = "shuts";
      string fileText = File.ReadAllText(fName);
      if (Regex.Match(fileText, GetWordPattern(myWord), RegexOptions.Multiline | RegexOptions.IgnoreCase).Success)
      {
        //You matched!
        System.Diagnostics.Debugger.Break();
      }
    }
    private static void TestRegex()
    {
      //I want to find the word went in the input text.
      const string myWord = "went";
      if (Regex.Match("I went to the store", GetWordPattern(myWord), RegexOptions.Multiline | RegexOptions.IgnoreCase).Success == false)
        throw new InvalidProgramException("It should have matched");
      if (Regex.Match("I went, to the store", GetWordPattern(myWord), RegexOptions.Multiline | RegexOptions.IgnoreCase).Success == false)
        throw new InvalidProgramException("It should have matched");
      if (Regex.Match("I wenta to the store", GetWordPattern(myWord), RegexOptions.Multiline | RegexOptions.IgnoreCase).Success == true)
        throw new InvalidProgramException("It should NOT have matched");
      if (Regex.Match("I awent to the store", GetWordPattern(myWord), RegexOptions.Multiline | RegexOptions.IgnoreCase).Success == true)
        throw new InvalidProgramException("It should NOT have matched");
    }
    private static string GetWordPattern(string Word)
    {
      //matches any single word on a word boundary.
      return string.Format(@"\b{0}\b", Regex.Escape(Word));
    }
  }
}

In this case i read the entire contents of a file to a single string variable. If this is unacceptable and you have to read the file line by line then that is OK -- just compare each line of the file. Be sure you use the static Regex.Match() because when you feed the static regex matcher a pattern it compiles the pattern and holds on to it -- increasing performance. This is not true with instantiated RegEx matches (unless you go way out of your way to compile the expression in to the assembly....)

Here:

using System;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace daniweb
{
  public partial class frmRegex : Form
  {
    public frmRegex()
    {
      InitializeComponent();
    }
    private void button1_Click(object sender, EventArgs e)
    {
      //To prove the regex works
      TestRegex();

      //Now to really match
      const string fName = @"C:\test.txt";
      const string myWord = "shuts";
      string fileText = File.ReadAllText(fName);
      if (Regex.Match(fileText, GetWordPattern(myWord), RegexOptions.Multiline | RegexOptions.IgnoreCase).Success)
      {
        //You matched!
        System.Diagnostics.Debugger.Break();
      }
    }
    private static void TestRegex()
    {
      //I want to find the word went in the input text.
      const string myWord = "went";
      if (Regex.Match("I went to the store", GetWordPattern(myWord), RegexOptions.Multiline | RegexOptions.IgnoreCase).Success == false)
        throw new InvalidProgramException("It should have matched");
      if (Regex.Match("I went, to the store", GetWordPattern(myWord), RegexOptions.Multiline | RegexOptions.IgnoreCase).Success == false)
        throw new InvalidProgramException("It should have matched");
      if (Regex.Match("I wenta to the store", GetWordPattern(myWord), RegexOptions.Multiline | RegexOptions.IgnoreCase).Success == true)
        throw new InvalidProgramException("It should NOT have matched");
      if (Regex.Match("I awent to the store", GetWordPattern(myWord), RegexOptions.Multiline | RegexOptions.IgnoreCase).Success == true)
        throw new InvalidProgramException("It should NOT have matched");
    }
    private static string GetWordPattern(string Word)
    {
      //matches any single word on a word boundary.
      return string.Format(@"\b{0}\b", Regex.Escape(Word));
    }
  }
}

In this case i read the entire contents of a file to a single string variable. If this is unacceptable and you have to read the file line by line then that is OK -- just compare each line of the file. Be sure you use the static Regex.Match() because when you feed the static regex matcher a pattern it compiles the pattern and holds on to it -- increasing performance. This is not true with instantiated RegEx matches (unless you go way out of your way to compile the expression in to the assembly....)

I have tried your code and it is very slow compared with the code listed in post #18 method 2... But thank you anyway

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.