RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

My Simple C-Sharp Questions:

Jeff

Lord
Let me start with your flashback question... This link is probably one of the best out there for string formatting questions and lookup..(http://blog.stevex.net/string-formatting-in-csharp/). The very first example is regarding ,# formatting.

Now, back to the "Question 4" topic....the best way I can explain how to do what you were attempting to do is with a highly commented example...
Code:
    class Program
    {
        static void Main(string[] args)
        {
            // Read in our lines from the file.
            string[] lines = System.IO.File.ReadAllLines(@"C:\Test.txt");

            Console.WriteLine("what word would you like to translate?");

            // Wait for user input
            string toMatch = Console.ReadLine();


            // We want to make a list not an array to store the results.
            // Arrays are fixed in size, and we do not know how many matches
            // will be returned.  A List is a variable size and can grow in size
            // if required.
            List<string> results = new List<string>();

            // Loop through each of the lines from the file.
            foreach (string s in lines)
            {
                // If there is no match found, we can just continue to the next line
                // There are 2 ways to do this you can either check for a match and if successful
                // add to the results list... or do as I have done here and move on.
                // I tend to have most of my if statements be a line of defence for the unwanted...
                // In this case we want a match, and if we don't have one, we move on.  This avoids heavy nesting when
                // writing complex functionality and quite a good habbit to get into.
                if (!Regex.IsMatch(s, toMatch, RegexOptions.IgnoreCase))
                {
                    continue;
                }

                // A match was found above, so we save that match to the results list.
                results.Add(s);
            }

            // Output some statistical data.
            Console.WriteLine("{0} matchs for '{1}' found", results.Count, toMatch);

            // Loop through the results
            foreach (string result in results)
            {
                // Display them to the screen
                Console.WriteLine(result);
            }

            Console.WriteLine("Press any key to exit...");
            Console.Read();
        }
    }
Let me know if you have any questions
 

sec_goat

Squire
Let me know if you have any questions

I am kicking my self over this one. I was able to look at my first example which I used from MSDN or something and figure out what Namespace Regex is hiding in, but What namespace is List hiding in?

EDIT: found it! System.Collections.Generic;

Now I am goign to attempt to get it to display only the second half of a string based on a delimiter I specify, and looping through much like the example you have for matching the strings in the first place.

EDIT 2: I am looking at getting it to output part of the string by using RESULT.SUBSTRING(5,20). But this is not the end answer as all the strings would have to have the same length and have the delimiter in the same place. Is there a way to iterate through a string's characters and count the place of the delimiter and the total number of chars so I could feed that to substring?
EDIT 2a: It looks like I can use result.length to give me the end character count.
I continue my search!
 

Jeff

Lord
You know, if you are editing the code with Visual Studio... if you have spelled a class correctly (including upper case where appropriate) you will see a red _ (underscore) at the first letter of the class name... if you press Alt+Shift+F10, you will get a context menu to resolve the namespace... which will automatically add it to the top of the code page.
 

sec_goat

Squire
You know, if you are editing the code with Visual Studio... if you have spelled a class correctly (including upper case where appropriate) you will see a red _ (underscore) at the first letter of the class name... if you press Alt+Shift+F10, you will get a context menu to resolve the namespace... which will automatically add it to the top of the code page.
Very Nice, I was kind of juggling between VCSE and Sharp Develop to see which I liked better. SD is less of a memory hog on my system it seems, but VCSE seems to offer better advice for me. Thanks for that tip.
 

daat99

Moderator
Staff member
Instead of the regular expression try the following:

The "line.indexOf(specialChar)" will return the index of the first occurrence of the "specialChar" you want.

You can use that index as an argument to the "result = line.substring(start, length)" method (use it +1 to get the string from the next character).

After you do that you may want to do "result.trim()" to remove the extra spaces from the start and end of the resulting string.

So it'll look like this:
Code:
result = line.substring( line.indexOf(specialChar) + 1 );
result = result.trim();
or in a 1 liner:
Code:
result = line.substring( line.indexOf(specialChar) + 1 ).trim();

PS
You may need to correct some case-sensitive typos.
 

sec_goat

Squire
Instead of the regular expression try the following:

The "line.indexOf(specialChar)" will return the index of the first occurrence of the "specialChar" you want.

You can use that index as an argument to the "result = line.substring(start, length)" method (use it +1 to get the string from the next character).

After you do that you may want to do "result.trim()" to remove the extra spaces from the start and end of the resulting string.

So it'll look like this:
Code:
result = line.substring( line.indexOf(specialChar) + 1 );
result = result.trim();
or in a 1 liner:
Code:
result = line.substring( line.indexOf(specialChar) + 1 ).trim();

PS
You may need to correct some case-sensitive typos.

Wow some how I had missed these new posts in regards to my questions. Thank you Daat I appreciate it, after some extensive digging I came up with much the same solutions.

here is what I have to find the special char and to display what part of the string I want, It appears to do exactly as I want it to.
Code:
int delimiter = result.IndexOf(@",");

result.Substring(delimiter+1));

I grabbed this from some blog and not sure exactly what the @ sign is for or if I need it? Also is it better to do (delimiter) + 1 instead of how I have it?

Thanks again to all who are helping me with this!


EDIT: ok I looked up the @ symbol and know that it tells the compiler to use the string verbatim and ignore and escape characters. . that explains why it is used in the datapath.cs file to tell it where to find the UO directory.
 

Jeff

Lord
Ya, pointless to use for @"," since there are no escape characters, just a comma. Also, delimiter + 1 is fine.
 

daat99

Moderator
Staff member
I wouldn't use the @ symbol in your case because your char doesn't require the escape character.

And as for your solution I would still add the Trim() method to it before I store the result in order to get rid of extra spaces in the string (this will actually get you my solution exactly).

Personally I won't waste space on the heap by saving the "indexOf()" result in an integer either but that's just me :).
 

sec_goat

Squire
I wouldn't use the @ symbol in your case because your char doesn't require the escape character.

And as for your solution I would still add the Trim() method to it before I store the result in order to get rid of extra spaces in the string (this will actually get you my solution exactly).

Personally I won't waste space on the heap by saving the "indexOf()" result in an integer either but that's just me :).

Instead would i try something like this?
Code:
result.Substring(indexOf(",")+1)
 

Jeff

Lord
Personally I won't waste space on the heap by saving the "indexOf()" result in an integer either but that's just me :).
First, it probably wouldnt go in the heap, it'd be on the stack... Second, it is a better practice to not do
Code:
result.Substring(result.IndexOf(",")+1)
because it makes it impossible to debug. It seems to be a common trend amongst young (not many years under their belt) developers to try to inline anything, when in reality it is the compilers that chooses to inline, not you... it can even take out your in-lining at compile time.
 

sec_goat

Squire
I kinda of assumed doing something like that would cause problems. At least if I have it in the Int Variable I can see what it is before I use it in the substring.

Now how much space would this actually take up? I assume in larger scale it is something you want to watch for and not use unnecessary variables for memory concern. And If it is on the stack instead of the heap is it as much of a concern since it goes away once the function is done?
 

Jeff

Lord
Nothing for you to worry about... even at a large scale... my whole point is that writing it in a condensed format really only makes things difficult to read. Personally, the optimization benefit (if any) does not out weigh the maintainability of the code. ... Some people try to optimize things they don't truely understand, which doesn't really optimize, and/or just makes things more complicated.

The only time you should even remotely consider these types of optimizations is if you are writing code that iterates a large number of times over a short period of time.

As for the stack vs heap question, the stack is always faster to allocate to, in general, all value types in .Net allocate to the stack (especially in local scope)... although, this is not always the case (welcome to managed code ;) )... but since int is a value type, you should assume that it is going to be allocated to the stack. I even took the time to take the following code
Code:
        static void Main(string[] args)
        {
            int index = Test.IndexOf(',') + 1;
            string result = Test.Substring(index);

            Console.WriteLine(result);
        }
and took a look at the IL that is generated... sure enough, index is stack allocated.
Code:
    L_0000: ldstr "This is my, Test String"
    L_0005: ldc.i4.s 0x2c
    L_0007: callvirt instance int32 [mscorlib]System.String::IndexOf(char)
    L_000c: ldc.i4.1
    L_000d: add
    L_000e: stloc.0
The above code works as follows:
  1. L_0000 - load string into memory
  2. L_0005 - push the value 0x2c to the stack (0x2c is a comma, it is the comma we are pushing to IndexOf
  3. L_0007 - Call the function
  4. L_000c - Push the value of 1 to the stack, this is the + 1 after IndexOf in my code.
  5. L_000d - Add the 2 values on the stack together (add pops the 2 values out of the stack and adds them, our to values on the stack at the moment are the return result from IndexOf, and the + 1)
  6. L_000e - Pops the value out of the evaluation stack and into a local variable list at index 0. This is "int index"
Hope this helps a little, learning how programming works at this level is important. If you want to learn it, the best way is to write a simple app like i did above, get the application called "Reflector" and open your assembly in it, once open you can disassemble a method and change the code from C# to IL, mousing over the IL will give you a tool tip explaining the operation.
 

daat99

Moderator
Staff member
First, it probably wouldnt go in the heap, it'd be on the stack... Second, it is a better practice to not do
Code:
result.Substring(result.IndexOf(",")+1)
because it makes it impossible to debug. It seems to be a common trend amongst young (not many years under their belt) developers to try to inline anything, when in reality it is the compilers that chooses to inline, not you... it can even take out your in-lining at compile time.
Thanks for correcting me about the stack/heap thing, it's always good to learn new things.

As for the "inline" part, this is a matter of opinion.

We both should have about 10 years of experience under our belts and we both handle code in our work but we still differ in this part (not that it's a bad thing).

In my opinion, as long as the inline is simple and short then it won't be harder to maintain.

As for debugging it, of course I'll break them into 2 lines during the debugging session, I'll just inline them when I'm, done :)

Personally, I prefer to see as much code on-screen as possible at any given time.

Breaking every tiny little thing to multiple lines might be easier to understand for the novice programmer but you may end up missing the big picture the code tries to "paint".


Instead would i try something like this?
Code:
result.Substring(indexOf(",")+1)
You should keep in mind that the substring method returns a string but doesn't change the string that called it.

When I need to do something like this I use (trimming white spaces from the end/start and adding the comment):
Code:
string result = line.Substring(line.indexOf(',')+1).Trim(); //get the string after the comma without leading/trailing spaces

In the rare occasions where I need to debug this then I'll do:
Code:
int comma = line.indexOf(',');
string after = line.Substring(comma+1);
string result = after.Trim();
//string result = line.Substring(line.indexOf(',')+1).Trim(); //get the string after the comma without leading/trailing spaces
 

Jeff

Lord
Daat, i also program from the point of view that it isnt just me looking at the code. I work on a team of over 12 developers, so im constantly trying to make sure my code is easy to understand. Also, as for the debugging part, i completely disagree with having to CHANGE the code to debug it, When you are debugging large scale applications, the last thing you want to do is go in and change several lines of code just to make it easy to debug.... then have to change them back.

Not to mention, in this exact case... there is an inherent flaw in your functionality... There should be a check for -1 from the result of IndexOf... in that case, you would have to use a variable...
 

daat99

Moderator
Staff member
Daat, i also program from the point of view that it isnt just me looking at the code. I work on a team of over 12 developers, so im constantly trying to make sure my code is easy to understand. Also, as for the debugging part, i completely disagree with having to CHANGE the code to debug it, When you are debugging large scale applications, the last thing you want to do is go in and change several lines of code just to make it easy to debug.... then have to change them back.

Not to mention, in this exact case... there is an inherent flaw in your functionality... There should be a check for -1 from the result of IndexOf... in that case, you would have to use a variable...
1. I'm also part of a team and the code I write is part of a tool that is used and modified by over 100 employees (every one can change everything and that can effect everybody else in return).
2. In my experience the debugging sessions are mostly limited to a very short segment of code (well, we debug it intensely before we upload it to the UCM server) so it doesn't matter much in the long run if you change it for debugging (although I rarely need to).
3. He said that he writes the text file so I wrote the code in the assumption that his text file is valid.
You are right that if the validity of the source data is in question then my solution won't fit and yours will be better though.
Please keep in mind that in case of a non-existent comma in the line then my code will return the entire line, it won't crash (that may be useful behavior in some cases).
 
Top