0

I'm trying to figure out if the text URL that I get from current URL exists in 'linkx.txt', if it does then show a message, if it doesn't then write to text file. however, when I run this code program writes to text file twice before recognizing the text exists.

[working code]

  protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
    string linkx = @"Desktop\linkx.txt";
    string url = "";
    if (keyData == Keys.F1) { Application.Exit(); return true; }
    else if (keyData == Keys.F2) { url = webBrowser1.Url.AbsoluteUri; return true; }

    using (StreamReader sr = File.OpenText(linkx))
    {
        string texxt = url;
        string[] lines = File.ReadAllLines(linkx);
        bool matched = false;
        for (int x = 0; x < lines.Length; x++)
        {
            if (texxt == lines[x])
            {
                sr.Close();
                MessageBox.Show("there is a match");
                matched = true;
            }
        }
        if (!matched)
        {
            sr.Close();
            using (StreamWriter wriite = File.AppendText(linkx))
            {
                wriite.WriteLine(url);
                MessageBox.Show("url copied!");
                return true;    // indicate that you handled this keystroke
            }
        }
    }
    // Call the base class
    return base.ProcessCmdKey(ref msg, keyData);
}
Ryze2
  • 31
  • 1
  • 4
  • 1
    `lines.Contains(textxx)` Note this will check that `textxx` matches the **entirety** of a line - it won't match if it was (for example) only **part** of one of the lines. – mjwills Aug 29 '18 at 22:26
  • Possible duplicate of [c# search string in txt file](https://stackoverflow.com/questions/12856471/c-sharp-search-string-in-txt-file) – 41686d6564 stands w. Palestine Aug 29 '18 at 22:27
  • @emsimpson92 Of course it does, but it won't match a word in a line of individual entry but rather the whole line. `String.Contains` does not work the same way `Array.Contains`. – Adrian Aug 29 '18 at 22:33
  • That's true, but if the URL doesn't exist in the file he wants to write it to the file, so It's most likely a text file full of URLs – emsimpson92 Aug 29 '18 at 22:34
  • If you are reading a very large text file, you may want to read it line by line and do the search on each line. There's no need to read the entire file into memory. – Flydog57 Aug 29 '18 at 22:57

2 Answers2

3

It's a lot simpler than what you've got. If you've just got an array of strings you can use Array.Contains.

var lines = File.ReadAllLines("links.txt");

if (!lines.Contains("google.com")) {
  File.AppendAllText("links.txt", "google.com");
}
Ryan
  • 7,733
  • 10
  • 61
  • 106
  • This is still prone to the same problem OP has. Use `ReadAllText` and `String.Contains` instead. – Sani Huttunen Aug 29 '18 at 22:31
  • @SaniSinghHuttunen I think the OP's problem is that he's not looping through all the lines...he quits just before the last one – Rufus L Aug 29 '18 at 22:35
  • @RufusL: That is one of the problems. The other is that there is no guarantee that `texxt` will ever equal any line. What if a line begins with a space? " google.com" and you search for "google.com". Will it find it with `Array.Contains`? Or `texxt == lines[x]`? – Sani Huttunen Aug 29 '18 at 22:38
  • True, my only clue was he said, *"when I run this code program writes to text file twice before recognizing the text exists"* – Rufus L Aug 29 '18 at 22:40
2

"when I run this code program writes to text file twice before recognizing the text exists"

The main problem with your code is in this condition:

for (int x = 0; x < lines.Length - 1; x++)

You are looping through all the lines except the last one, which is likely the one you're searching for in this case.

To resolve this, just remove the - 1 from your exit condition.


With that being said, your code can be simplified greatly if you use the static ReadLines and AppendAllText methods of the File class:

/// <summary>
/// Searches the specified file for the url and adds it if it doesn't exist.
/// If the specified file does not exist, it will be created.
/// </summary>
/// <param name="filePath">The path to the file to query.</param>
/// <param name="url">The url to search for and add to the file.</param>
/// <returns>True if the url was added, otherwise false.</returns>
protected static bool AddUrlIfNotExist(string filePath, string url)
{
    if (!File.Exists(filePath)) File.Create(filePath).Close();

    if (!File.ReadLines(filePath).Any(line => line.Contains(url)))
    {
        File.AppendAllText(filePath, url);
        return true;
    }

    return false;
}

Then this method could be used in your code like:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
    if (keyData == Keys.F1) { Application.Exit(); return true; }

    if (keyData == Keys.F2)
    {
        if (AddUrlIfNotExist("linkx.txt", webBrowser1.Url.AbsoluteUri))
        {
            MessageBox.Show("url copied!");
        }
        else
        {
            MessageBox.Show("there is a match");
        }
    }

    // Call the base class
    return base.ProcessCmdKey(ref msg, keyData);
}
Rufus L
  • 36,127
  • 5
  • 30
  • 43