|
|
|
At this point, you may be growing tired of fiddling around with numbers, and math, and input and output. You want to create a program that actually does something, right? Well, don't worry, we're almost ready to start applying the things we've learned. There's just one last thing we need to cover. We've already learned how to manipulate numbers... we now need a brief lesson in manipulating text, as well! String (or "text") manipulation is even more self-contained than numeric manipulation's "Math" class. You don't need an extra class to perform special string functions, because every string variable you create already has access to a wide variety of useful functions it can perform on itself. For example, the following code prints out the contents of a string in uppercase: string test = "Testing the various functions of STRINGS!"; Console.WriteLine(test.ToUpper()); The result of that code would be: TESTING THE VARIOUS FUNCTIONS OF STRINGS! We can also store the results of the conversion in another string for later use... string testUpper = test.ToUpper(); Console.WriteLine(testUpper); And we can even overwrite the original string with it's own conversion: testUpper = testUpper.ToUpper(); Just remember to use the "=" sign so that you're actually assigning the value of the conversion. The following line of code accomplishes nothing: testUpper.ToUpper(); Just as calling ReadLine() without assigning the result to something will not store the user input, calling ToUpper() without assigning it to something will not store the results of the conversion. ToUpper() also has a twin called ToLower(). Guess what it does? Without bothering to answer such a silly question, let us move on to the next area, string analysis. You can use a string's Length function to see how many characters it contains: string name = "Bartholomew"; int length = name.Length; Console.WriteLine("Length of Name: " + length); You can use a string's StartsWith() and EndsWith() functions to find out if a string begins or ends with a specific sequence of letters. Note the following examples: Console.WriteLine("Starts with \"Ba\"?\t" + name.StartsWith("Ba")); Console.WriteLine("Starts with \"Bart\"?\t" + name.StartsWith("Bart")); Console.WriteLine("Starts with \"Barter\"?\t" + name.StartsWith("Barter")); Console.WriteLine("Ends with \"mew\"?\t" + name.EndsWith("mew")); The first two tests will display "True" on the console, since name contains a value of "Bartholomew", and that value begins with both "Ba" and "Bart". However, it doesn't start with "Barter", so the third line will display "False" on the console. The fourth line will display "True" again, because "Bartholomew" ends with "mew". You might wonder how C# knows to write the actual words "True" and "False" to the console. The reason is that BeginsWith() and EndsWith() return a type of variable we haven't seen yet, "bool". This is a special type of variable that can only store one of two possible values, "True" or "False". As we will see in the next unit, this is a tremendously useful datatype, but for now just let it print on the screen and don't worry about it. Another fun (ha, ha!) thing to do with strings is find specific words and letters in them. Consider the following code: Console.WriteLine("First index of 'B': " + name.IndexOf("B")); Console.WriteLine("First index of 'a': " + name.IndexOf("a")); Console.WriteLine("First index of 'r': " + name.IndexOf("r")); Console.WriteLine(" Last index of 'o': " + name.LastIndexOf("o")); Run this code, and you will get the following output: First index of 'B': 0 First index of 'a': 1 First index of 'r': 2 Last index of 'o': 7 As you can see, the IndexOf() methods are returning the position in the string where it found the text you're looking for (and you're allowed to search for multiple characters, by the way, not just single letters as I've done here). Note, however, that the first letter of the string, "B", is considered index 0. The second letter of the string, "a", is considered index 1, and so on. In programming, virtually all indexed collections start at zero, not one (Oh, you'd prefer that they started at one? Get over it). LastIndexOf() works the same way, except it obviously returns the last index in the string where it found your text. So, we now have an easy way to find both the first and last occurrences of text within a string. What if we want to find one that's in between? In this case, we'd call IndexOf(), but provide a specific starting point... int firstIndex = name.IndexOf("o"); Console.WriteLine("First index of 'o': " + firstIndex); int secondIndex = name.IndexOf("o", firstIndex+1); Console.WriteLine(" 2nd index of 'o': " + secondIndex); int thirdIndex = name.IndexOf("o", secondIndex+1); Console.WriteLine(" 3rd index of 'o': " + thirdIndex); This code will produce the following output: First index of 'o': 5 2nd index of 'o': 7 3rd index of 'o': -1 The first call to IndexOf() is the same one we did before. In the second call, however, we provide the index that we got from the first call. You might wonder, why did we add one to it? Because we want to continue searching after the index of the previous occurrence. If we start our next search at the index of the previous occurrence, we'll just hit the previous occurrence again. What about that -1 that's returned for the third index? Well, -1 has special meaning in many areas of programming. It's often used as a unique flag for "not applicable", or "out of range". And since there isn't a third occurrence of 'o' in "Bartholomew", it makes perfect sense that we got this "out of range" flag as our result. Now let's try some formatting tricks. You've already seen how "\t" can be used to insert tabs (and therefore line up several rows of text), but let's try something more sophisticated... string season1 = "spring", season2 = "summer", season3 = "fall", season4 = "winter"; Console.WriteLine(season1.PadLeft(10, '.')); Console.WriteLine(season2.PadLeft(10, '.')); Console.WriteLine(season3.PadLeft(10, '.')); Console.WriteLine(season4.PadLeft(10, '.')); The above code yields the following output: ....spring ....summer ......fall ....winter In this case, we supplied PadLeft() with two parameters: a number and a character. (Note that single characters are enclosed in single quotes, and strings are enclosed in double quotes). The number is the total length that we want the string to be. And as you can see, each line of output is exactly 10 characters long. If the string is less than 10 characters, it "pads" extra characters to the string's left until it reaches the correct length. The character that we've supplied tells PadLeft() which character to pad with. There's also a PadRight(), of course, but I won't bore you with the details. The opposite of padding a string is trimming it. We can use TrimStart() and TrimEnd() to remove unwanted characters from the beginning and end of a string, or Trim() to remove unwanted characters from both ends. They're about as simple as you can get: string rubbish = ".........hello....."; Console.WriteLine(rubbish); Console.WriteLine(rubbish.TrimEnd('.')); Console.WriteLine(rubbish.TrimStart('.')); Console.WriteLine(rubbish.Trim('.')); The above code produces the following output: .........hello..... .........hello hello..... hello Easy, right? We just supply the Trim() function with the character we want to eliminate, and let C# take care of the rest. The last thing we're going to cover is substrings. There are many occasions in programming when you only want to snag a specific part of a larger string, and Substring() is the way we accomplish this. Here are a few examples: string name2 = name.Substring(0, 5); string name3 = name.Substring(4, 2); string name4 = name.Substring(5, name.Length-5); Console.WriteLine(name2); Console.WriteLine(name3); Console.WriteLine(name4); Assuming that the content of name is still "Bartholomew", we would get the following ouput: Barth ho olomew In case you want it spelled out for you (I usually do), the first number you give Substring is starting index in your original string, and the second number is the total length of the substring. The first substring we requested begins at character 0, and has a total length of 5. So, it begins with the first letter in name, followed by next four characters (for a total of five characters, which is the same quantity that we requested). The resulting substring is "Barth". Be careful when using substrings. If you ask for a substring that goes beyond the original string's length, your program will crash. For example, "Bartholomew" is 11 characters long (and you can call its Length method if you don't believe me). If we asked for a substring that started on character 10, and went on for another 8 characters, the program would crash. There is only one available character after index 10, so you can't go on for another 8 characters! For some really powerful substring capabilities, look into the Regex namespace. It's too big to include a detailed explanation in this introductory unit, but it's something you should be aware of. When it's used correctly, it can save you a lot of messing around with IndexOf() and Substring()! If you've been following the previous five lessons (including this one), you now have an absolutely rock-solid foundation to start building your skills on. It's finally time to start making programs that actually do stuff! But first, a code sample. using System; namespace E_StringManipulation { class Class1 { [STAThread] static void Main(string[] args) { // Converting to uppercase and lowercase string test = "Testing the various functions of STRINGS!"; string testUpper = test.ToUpper(); string testLower = test.ToLower(); Console.WriteLine(test); Console.WriteLine(testUpper); Console.WriteLine(testLower); // Finding length, prefixes and postfixes in a string string name = "Bartholomew"; Console.WriteLine(Environment.NewLine + "Name = " + name); Console.WriteLine("Length of Name:\t\t" + name.Length); Console.WriteLine("Starts with \"Ba\"?\t" + name.StartsWith("Ba")); Console.WriteLine("Starts with \"Bart\"?\t" + name.StartsWith("Bart")); Console.WriteLine("Starts with \"Barter\"?\t" + name.StartsWith("Barter")); Console.WriteLine("Ends with \"mew\"?\t" + name.EndsWith("mew")); // Finding the index of text in a string Console.WriteLine(Environment.NewLine + "First index of 'B': " + name.IndexOf("B")); Console.WriteLine("First index of 'a': " + name.IndexOf("a")); Console.WriteLine("First index of 'r': " + name.IndexOf("r")); int firstIndex = name.IndexOf("o"); Console.WriteLine("First index of 'o': " + firstIndex); int secondIndex = name.IndexOf("o", firstIndex+1); Console.WriteLine(" 2nd index of 'o': " + secondIndex); int thirdIndex = name.IndexOf("o", secondIndex+1); Console.WriteLine(" 3rd index of 'o': " + thirdIndex); Console.WriteLine(" Last index of 'o': " + name.LastIndexOf("o")); // Padding string season1 = "spring", season2 = "summer", season3 = "fall", season4 = "winter"; Console.WriteLine(Environment.NewLine + season1.PadLeft(10, '.')); Console.WriteLine(season2.PadLeft(10, '.')); Console.WriteLine(season3.PadLeft(10, '.')); Console.WriteLine(season4.PadLeft(10, '.')); // Trimming string rubbish = ".........hello....."; Console.WriteLine(Environment.NewLine + rubbish); Console.WriteLine(rubbish.TrimEnd('.')); Console.WriteLine(rubbish.TrimStart('.')); Console.WriteLine(rubbish.Trim('.')); // Substrings string name2 = name.Substring(0, 5); string name3 = name.Substring(4, 2); string name4 = name.Substring(5, name.Length-5); Console.WriteLine(Environment.NewLine + name2); Console.WriteLine(name3); Console.WriteLine(name4); // Prompt for exit Console.Write(Environment.NewLine + "Program complete! Hit enter to exit..."); Console.ReadLine(); } } } |
|