CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 19
  1. #1
    Join Date
    Mar 2012
    Posts
    14

    [RESOLVED] Need Help with Parser C#

    Okay, I'm making an application on Visual Studio 2010 that will load a CSV file with Text in it such as:

    black, white
    Cat, dog
    Hot, cold

    and so on. So they're separated by a comma. I want to use the loaded file with a streamreader and store the data in a dictionary. I then want to split the text in the file so that the word before the comma could be assigned to [0] and the word after the comma could be assigned to [1] This means that if the user entered a [0] textword into textbox 1 then after clicking a button textword [1] would show in textbox 2. For example,

    User enters black in Textbox 1 and then after clicking a button white is now shown in Textbox 2.
    User enters Cat in Textbox 1 and then after clicking a button Dog is now shown in Textbox 2.

    Here is the code that I currently have:

    Code:
    //Dictionary Load Button
            private void button1_Click_1(object sender, EventArgs e)
            {
                if (openFileDialog1.ShowDialog() == DialogResult.OK)   //Allows the user to choose the dictionary to load
                
                {  
                   Dictionary<string, int> d = new Dictionary<string, int>();
                   using (StreamReader sr = new StreamReader(openFileDialog1.FileName))
    
                   {
                      string line;
                      while ((line = sr.ReadLine()) != null)
                      {
                          string[] splitword = line.Split(',');
                         
                                         
                                              
                      }
                                  
                   }
                        
                }
    After string[] splitword = line.Split(','); I don't know how to do the rest. Such as assigning [0] and [1] and then the text box code.


    Any help with this would be fully appreciated as I've went to the end of the earth and back trying to figure this out.
    I've had it looked over by my tutor and so far everthing's correct.
    Last edited by Cimperiali; March 17th, 2012 at 01:52 PM. Reason: Added [code][/code] tags

  2. #2
    Join Date
    Jan 2009
    Posts
    596

    Re: Need Help with Parser C#

    As you want to lookup a string (e.g. 'black') in the Dictionary and get another string (e.g. 'white') out, you should be defining your dictionary as
    Code:
    Dictionary<string, string>
    Then after this line:
    Code:
    string[] splitword = line.Split(',');
    you can access the first word (the key) as splitword[0] and the second (the value) as splitword[1]. So to add this to the dictionary you would do:
    Code:
    d.Add(splitword[0], splitword[1]);
    (make sure you check there are two and only two entries in splitword first, though).

    Finally, use the Dictionary.Item() method to look up the value corresponding to a key. Do this when the user clicks the button. Note that this throws an exception (KeyNotFoundException) if the key doesn't exist in the dictionary, so you either need to be prepared to handle this or check whether the key is in the dictionary first by using Dictionary.ContainsKey().

  3. #3
    Join Date
    Mar 2012
    Posts
    14

    Re: Need Help with Parser C#

    Ok thanks, that's just what I was looking for!
    However I tried to use a Try and Catch method and i can't see why it isnt working

    Code:
    try
                          {
                              outputBx.Text = "" + d[inputBx.Text];
                          }
                          catch (Exception ex1)
                          {
                              outputBx.Text = "Not found";
                          }
    Any help on this? or how i'd use a TryGetValue. I only ask to use this instead of the contains key method is because i've been told that TryGetValue is a lot more efficient than contains key for use with a dictionary.

  4. #4
    Join Date
    Jan 2009
    Posts
    596

    Re: Need Help with Parser C#

    Quote Originally Posted by dahrull View Post
    Ok thanks, that's just what I was looking for!
    However I tried to use a Try and Catch method and i can't see why it isnt working

    Code:
    try
                          {
                              outputBx.Text = "" + d[inputBx.Text];
                          }
                          catch (Exception ex1)
                          {
                              outputBx.Text = "Not found";
                          }
    Any help on this? or how i'd use a TryGetValue. I only ask to use this instead of the contains key method is because i've been told that TryGetValue is a lot more efficient than contains key for use with a dictionary.
    I don't see anything wrong with that code - it should be doing what it looks like it will do. What exact problem are you having with it?

    As for TryGetValue, it is more efficient in the case that you are asking for a lot of keys which aren't in the dictionary. This is because it effectively is the same as checking the key is present (i.e. ContainsKey) before indexing it (i.e. Item). It therefore prevents lots of KeyNotFoundExceptions being thrown in the indexing when the keys are not present.

    So it would be more efficient than what you are doing here (i.e. the try/catch) if you keep asking for non-existent keys.

    However, this really isn't going to be an issue for you as this is all running from a GUI anyway, meaning the rate-determining step will be the time it takes the user to click a button I'm not saying efficiency is not a concern in programming, but you shouldn't worry about it unless you find that your specific application is running too slowly for your purpose.

    As to how you would use TryGetValue, it would be like this:
    Code:
    string outputString = null;
    if (d.TryGetValue(inputBx.Text, out outputString)){
        // We have found the string
        outputBx.Text = outputString
    } else {
        // Haven't found it - do something else
    }
    It returns a boolean to indicate whether the key was found, and if it is the value is returned via an out parameter.

  5. #5
    Join Date
    Mar 2012
    Posts
    14

    Re: Need Help with Parser C#

    When I try to use the Try Catch method the form runs, however it doesn't work. No matter what I type into inputBx nothing will show in the outputBx.
    I'm wanting this to work with the click of a button, but right now the important thing is making sure it actually all works first.
    The exact same thing happens when I use TryGetValue.

    Perhaps you could look at my code as a whole to see if I'm doing something wrong.

    Code:
    //Dictionary Load Button
            private void button1_Click_1(object sender, EventArgs e)
            {
                if (openFileDialog1.ShowDialog() == DialogResult.OK)   //Allows the user to choose the dictionary to load
                
                {
                   Dictionary<string, string> d = new Dictionary<string, string>();
                   using (StreamReader sr = new StreamReader(openFileDialog1.FileName))
    
                   {
                      string line;
                      while ((line = sr.ReadLine()) != null)
                      {
                          string[] splitword = line.Split(',');
                          d.Add(splitword[0], splitword[1]);
    
                          string outputString = null;
                          if (d.TryGetValue(inputBx.Text, out outputString))
                          {
                              // We have found the string
                              outputBx.Text = outputString;
                          }
                          else
                          {
                              // Haven't found it - do something else
                          }
                          
    
                          
                      }
                                  
                   }
                        
                }
            }
    This returns no errors, runs the form, lets me load a text file for the streamreader but it still doesn't work with what I put into the text boxes

    EDIT: Maybe I actually have to do this on a button_click event before it will work. Either way i'm still stuck. I'll admit I'm a starter at c# so I'm still learning "the ropes"
    Last edited by dahrull; March 18th, 2012 at 07:47 AM. Reason: adding more

  6. #6
    Join Date
    Mar 2012
    Posts
    14

    Re: Need Help with Parser C#

    Okay, so I've created a button on my form, but I'm not sure what code I'd put in
    Code:
     private void btnTrans_Click(object sender, EventArgs e)
            {
                
    
            }
    btnTrans doesn't recognize "d" (dictionary). I think that's because it's not global but that brings me to the case that I have no idea how do to that either :/

  7. #7
    Join Date
    Jan 2009
    Posts
    596

    Re: Need Help with Parser C#

    Quote Originally Posted by dahrull View Post
    When I try to use the Try Catch method the form runs, however it doesn't work. No matter what I type into inputBx nothing will show in the outputBx.
    I'm wanting this to work with the click of a button, but right now the important thing is making sure it actually all works first.
    The exact same thing happens when I use TryGetValue.

    Perhaps you could look at my code as a whole to see if I'm doing something wrong.

    Code:
    //Dictionary Load Button
            private void button1_Click_1(object sender, EventArgs e)
            {
                if (openFileDialog1.ShowDialog() == DialogResult.OK)   //Allows the user to choose the dictionary to load
                
                {
                   Dictionary<string, string> d = new Dictionary<string, string>();
                   using (StreamReader sr = new StreamReader(openFileDialog1.FileName))
    
                   {
                      string line;
                      while ((line = sr.ReadLine()) != null)
                      {
                          string[] splitword = line.Split(',');
                          d.Add(splitword[0], splitword[1]);
    
                          string outputString = null;
                          if (d.TryGetValue(inputBx.Text, out outputString))
                          {
                              // We have found the string
                              outputBx.Text = outputString;
                          }
                          else
                          {
                              // Haven't found it - do something else
                          }
                          
    
                          
                      }
                                  
                   }
                        
                }
            }
    This returns no errors, runs the form, lets me load a text file for the streamreader but it still doesn't work with what I put into the text boxes

    EDIT: Maybe I actually have to do this on a button_click event before it will work. Either way i'm still stuck. I'll admit I'm a starter at c# so I'm still learning "the ropes"
    To (mis)quote the late, great Eric Morecambe, "you are using all the right code, but not necessarily in the right order"

    When the user clicks the button, your code is prompting the user for the dictionary file, reading it in (in the while loop) and (also in the while loop) checking in the dictionary. If you do want to read the file on each button click, it would be simpler just to check each line in turn against the text box. No need for a dictionary at all.

    But, the better design would be this (IMHO ):
    1) Read the file in when the dialog first opens, and set up the dictionary. This dictionary will need to be stored in the form so it can be accessed by the click handler.
    2) Let the user type what they want in the text box
    3) When the user clicks the button, check for this text in the dictionary, and set the output box appropriately.

    You could also have another button which would prompt for a new file when clicked, and recreate the dictionary based on this file.

  8. #8
    Join Date
    Mar 2012
    Posts
    14

    Re: Need Help with Parser C#

    Quote Originally Posted by Peter_B View Post
    To (mis)quote the late, great Eric Morecambe, "you are using all the right code, but not necessarily in the right order"

    When the user clicks the button, your code is prompting the user for the dictionary file, reading it in (in the while loop) and (also in the while loop) checking in the dictionary. If you do want to read the file on each button click, it would be simpler just to check each line in turn against the text box. No need for a dictionary at all.

    But, the better design would be this (IMHO ):
    1) Read the file in when the dialog first opens, and set up the dictionary. This dictionary will need to be stored in the form so it can be accessed by the click handler.
    2) Let the user type what they want in the text box
    3) When the user clicks the button, check for this text in the dictionary, and set the output box appropriately.

    You could also have another button which would prompt for a new file when clicked, and recreate the dictionary based on this file.
    That is what I'm aiming for I guess I sound pretty much all over the place but I really don't know how to sort out the code. I don't know which parts to split up to allow the dictionary to be stored in the form.

    EDIT: for example how would I put the click handler for the open dialog into this
    Code:
    private void Form1_Load(object sender, EventArgs e)
            {
    
            }
    If I could understand how to do that so the dictionary is stored in there, then I guess it would allow me to use the dictionary for the inputBx and outputBx with a click handler for the output
    Last edited by dahrull; March 18th, 2012 at 11:02 AM.

  9. #9
    Join Date
    Jan 2009
    Posts
    596

    Re: Need Help with Parser C#

    Quote Originally Posted by dahrull View Post
    EDIT: for example how would I put the click handler for the open dialog into this
    Code:
    private void Form1_Load(object sender, EventArgs e)
            {
    
            }
    If I could understand how to do that so the dictionary is stored in there, then I guess it would allow me to use the dictionary for the inputBx and outputBx with a click handler for the output
    Rather than calling the click handler in the Form1_Load method, it is better to have a separate method which you call from both Form1_Load and button1_Click_1. Call this something like LoadDictionary(). This will prompt the user for the file, and set up the dictionary.

    You already mostly have this method written in a previous post. I have taken out the bit which is doing the text lookup, and just left the bits which setup the dictionary:
    Code:
    Dictionary <string, string> d; // Data member in form
    
    private void LoadDictionary()
    {
        if (openFileDialog1.ShowDialog() == DialogResult.OK)   //Allows the user to choose the dictionary to load
        {
            d = new Dictionary<string, string>();
            using (StreamReader sr = new StreamReader(openFileDialog1.FileName))
            {
                string line;
                while ((line = sr.ReadLine()) != null)
                {
                    string[] splitword = line.Split(',');
                    // Remember to check that you have two entries in splitword
                    // before adding to the dictionary...
                    d.Add(splitword[0], splitword[1]);
                }
            }
        }
    }
    The dictionary variable should be declared in the form class, so it is accessible to all the event handlers.

  10. #10
    Join Date
    Mar 2012
    Posts
    14

    Re: Need Help with Parser C#

    Okay everything's finally starting to make a lot of sense and it seems to be a lot cleaner now.
    I now have:
    Code:
    private void btnTrans_Click(object sender, EventArgs e)
            {
                string outputString = null;
                if (d.TryGetValue(inputBx.Text, out outputString))
                {
                    outputBx.Text = outputString; //Found the string
                }
                else
                {
                    //Haven't found it - do something else
                }
                
            }
    As well as the changes I have made from your previous post.
    However, in your code, it doesn't allow me to set the button to load a file for the open dialog since my original code was in the click handler for load dictionary. There for I'm not able to open my CSV file.

    I really am trying to figure this out by myself, it's just i've sat here for days trying to do it and I feel right now that I'm so close to getting it right and understanding the code

    EDIT: IT WORKS!!! I can't thank you enough pal, you've really helped me understand how to do this. So happy that it words Peter_B IS THE DUDE!!
    Last edited by dahrull; March 18th, 2012 at 12:48 PM.

  11. #11
    Join Date
    Jan 2009
    Posts
    596

    Re: Need Help with Parser C#

    Quote Originally Posted by dahrull View Post
    However, in your code, it doesn't allow me to set the button to load a file for the open dialog since my original code was in the click handler for load dictionary. There for I'm not able to open my CSV file.

    I really am trying to figure this out by myself, it's just i've sat here for days trying to do it and I feel right now that I'm so close to getting it right and understanding the code
    Well, we all have problems when we start something new. But you're almost there .

    I don't understand the bit of your post I've put in bold though. You should be able to call the LoadDictionary() method from the click handler for the new button:
    Code:
    private void btnLoadDictionary_Click(object sender, EventArgs e)
            {
                LoadDictionary();
            }
    Have you tried this?

  12. #12
    Join Date
    Mar 2012
    Posts
    14

    Re: Need Help with Parser C#

    It works! So happy, what a class way to end the week. Kudos to you man!

  13. #13
    Join Date
    Jan 2009
    Posts
    596

    Re: Need Help with Parser C#

    Quote Originally Posted by dahrull View Post
    EDIT: IT WORKS!!! I can't thank you enough pal, you've really helped me understand how to do this.
    Ah - you got it working just before I submitted by last post. Glad it's working

    Quote Originally Posted by dahrull View Post
    So happy that it words Peter_B IS THE DUDE!!
    I think I might use this for my signature

  14. #14
    Join Date
    Mar 2012
    Posts
    14

    Re: Need Help with Parser C#

    Quote Originally Posted by Peter_B View Post
    Ah - you got it working just before I submitted by last post. Glad it's working


    I think I might use this for my signature
    Do it!
    I'm feeling slightly ambitious now, how easy would it be to add the option of adding a word to the dictionary if it hasn't been found?

  15. #15
    Join Date
    Jan 2009
    Posts
    596

    Re: Need Help with Parser C#

    Quote Originally Posted by dahrull View Post
    Do it!
    I'm feeling slightly ambitious now, how easy would it be to add the option of adding a word to the dictionary if it hasn't been found?
    This is quite straightforward, but has some things you will need to think about - I'll come to this later.
    First, let's consider adding the word to the dictionary. Your current code is:
    Code:
    private void btnTrans_Click(object sender, EventArgs e)
    {
        string outputString = null;
        if (d.TryGetValue(inputBx.Text, out outputString))
        {
            outputBx.Text = outputString; //Found the string
        }
        else
        {
            //Haven't found it - do something else
        }
    }
    So you need to add code to the else block to do this. Adding the new entry will just be another call to the Add method:
    Code:
    d.Add( inputBx.Text /*key*/, newValue /*value*/);
    we already have the key - this will be what the user entered in the input box. Getting the value ('newValue') will require prompting the user with a dialog box telling them that is not in the dictionary and asking for the value to associate with it.

    Now, the things you need to think about. Should the new values be written back to the file you originally read in? If they are then you can either append them each time you get a new entry (i.e. in the "Haven't found it - do something else" block) or save them up and write them en masse when the user changes to a new dictionary or when the form is closed. Writing them one at a time is simpler to code.

    To do this you will need to have a new data member to store the file name for the dictionary, so you know where to write them to. This should then be set when you open a new dictionary file, in the LoadDictionary() method.

Page 1 of 2 12 LastLast

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured