String Manipulation in C#

Concatenation Operator
 
The string data type does not contain any numeric value and therefore cannot be used in arithmetic operations but, the addition operator (+) is available for string operations. This can be used to concatenate two strings into one longer string.
 
string start = "This is a ";
string end = "concatenated string!";

string concat = start + end;    
// concat = "This is a concatenated string!"
 
The concatenation operator, like the addition operation, can be used as a compound assignment operator with the addition of an equals sign (+=).
 
string start = "This is a ";
string end = "concatenated string!";

start += end;                 // start = "This is a concatenated string!"
 
Relational Operators
 
The string data type supports the use of just two relational operators. These are for equality (= =) and inequality (!=) testing. The remainders of the relational operators are unavailable as they may only be used on data types that support the concept of ordering. It’s important to note that the relational operators perform comparisons that are case-sensitive as shown in the following examples:
 
string s1 = "String to compare.";
string s2 = "String to compare.";
string s3 = "String to Compare.";   // Note the capital 'C'
bool result;

result = s1 == s2;                  // result = true
result = s1 == s3;                  // result = false
result = s1 != s2;                  // result = false
result = s1 != s3;                  // result = true
 
Null Coalescing Operator
 
In the previous chapters of this tutorial we introduced the string data type as a class and explained that all strings are actually objects. It was also noted that all objects are nullable. This means that the null coalescing operator (??) can be used with strings when developing under .NET framework 2.0.
 
string notNullString = "A string";
string nullString = null;
string nullTestString;

nullTestString = notNullString ?? "Null";     // nullTestString = "A string"
nullTestString = nullString ?? "Null";       // nullTestString = "Null"
 
The null coalescing operator is not available in earlier versions of the .NET framework. If you are developing in version 1.1 or earlier, the same functionality can be provided using the conditional and equality operators.
 
string notNullString = "A string";
string nullString = null;
string nullTestString;

// Mimic the functionality of the null coalescing operator
nullTestString = notNullString == null ? "Null": notNullString;    
// "A string"
nullTestString = nullString == null ? "Null": nullString;    // "Null"
 
Converting Strings to Numeric Data Types
 
When we want to developing any software that requires user input,it is often, in that case the user is presented with a textbox or other control that allows text to be typed freely. The entered information is provided to the programmer’s code as the contents of a string. However, if the textbox is being used to allow the user to specify a number, this string may need to be converted to an appropriate numeric data type.
 
We have previously discussed that the possibilities for implicit and explicit conversion between numeric types using the cast functions. Casting is not available when converting between string and numeric values. Instead, .NET framework provides a ‘Convert’ class specifically designed for conversion between native types. The numeric classes also provide methods that allow strings to be parsed.
 
Convert Class
 
The .NET framework provides the Convert class within the System namespace. The class provides many conversion functions as static methods. For C# Fundamentals, it is enough to understand that when a method is static, it is used without first creating an object. In other words, we will not be creating a Convert object to access the methods we require.
 
.NET Structures and C# Keywords
 
One complication when using the Convert class is that native C# data types are named differently from the underlying .NET framework structures. This occurs to keep the keywords similar to those of the C and C++ languages that preceded C#.
 
The following table lists the numeric and Boolean data types that have been described before and the corresponding .NET framework structure name. The Convert class uses the case-sensitive .NET structure names.
 

C# Data Type

.NET Structure Name

bool Boolean
byte Byte
decimal Decimal
double Double
float Single
int Int32
long Int64
sbyte SByte
short Int16
uint UInt32
ulong UInt64
ushort UInt16
 
Conversion Syntax
 
The static conversion methods of the Convert class all follow a similar syntax. The method is named as the word ‘To’ followed by the desired resultant data type, using the .NET structure name. For example, to convert a string to a float, the method called is Convert.ToSingle (). The string value to be converted is provided as a parameter to the method.
 
// Convert a string to an integer
int stringToInt = System.Convert.ToInt32("25");

// Convert a string to a decimal
decimal stringToDecimal = System.Convert.ToDecimal("25.5");

// Booleans can be converted too
bool stringToBoolean = System.Convert.ToBoolean("true");
 
Note: The Convert method can be used without a reference to the System namespace because Visual Studio automatically includes the following line at the top of the code file:
 
using System;
 
The using statement tells the compiler which namespaces should be searched for classes automatically. Without this command, the namespace must be included in the code. As namespaces can have long names, this can become untidy and difficult to read. Without the using statement, conversion code would look like this:
 
int stringToInt = System.Convert.ToInt32(“25”);
 
Numeric Conversions with Convert
 
The Convert class is not only used for conversion from strings to other data types. Numeric data types may also be converted using this class before using casting functions. Where a floating point number is converted to an integer type, the result is rounded to the nearest whole number, unlike casting where the decimal part is truncated. However, unlike the standard rules of mathematical rounding, if the floating point number is exactly half way between two integers then the nearest even number is used.
 
decimal originalValue = 25.5M;
//Converting floating point number to an integer type
int converted = Convert.ToInt32(originalValue);     // Result is 26
//Casting floating point number to an integer type
int casted = (int)originalValue;                    // Result is 25
 
Parse Method
 
The numeric data type structures provide a Parse method by which strings can be converted into numbers. This method provides extra flexibility by allowing the developer to specify different styles of numeric string that can be converted. For example, allowing the use of currency symbols or hexadecimal numbers.
 
The Parse method is overloaded. This means that there are several ways to call the method, each using different parameters. We will examine two of the overloads in this section. In the given example we simply convert a string value into numeric value. The first takes a single string parameter holding the representation of the numeric value to be converted.
 
string toConvert = "100";
//Convert from string to int
int convertedInt = int.Parse(toConvert);            // Result is 100
//Convert from string to float
float convertedFloat = float.Parse(toConvert);      // Result is 100.0
 
Using Number Styles
 
The simple way of calling the Parse method described above has a drawback. The string containing the number must be formatted correctly with only numeric digits. but a number such as “£10,000” that is easily understood by the user causes an exception should it be parsed. To avoid this, a second parameter can be added to define the allowable number styles for the string contents.
 
The .NET framework provides an enumeration for the allowable number styles. Enumeration is a special value type that contains a named set of available values. It restricts the selection of values to items in this named set. Enumerations will be described before in this tutorial.
 
The NumberStyles enumeration is defined within the System.Globalization namespace. To avoid having to type System.Globalization before every reference to NumberStyles, add a using statement to the start of the code file.
 
using System.Globalization;
 
With the using statement added, we can use the NumberStyles enumeration as a second parameter to the Parse method.
 
// Conversion including thousands separator
int thousands = int.Parse("1,000", NumberStyles.AllowThousands);

// Conversion of value including a decimal point
float withDecimal = float.Parse("5.50", NumberStyles.AllowDecimalPoint);

// Conversion of value including a currency symbol
// (Make sure you change the currency symbol to match your local currency)
int withCurrency = int.Parse("£5", NumberStyles.AllowCurrencySymbol);
 
The NumberStyles enumeration values represent individual bits in an integer value. This means that we can combine multiple styles by using the OR operator (|).

For example:

 
// Conversion of value including a decimal point and currency symbol
float multiple = float.Parse("£5.50", 
  NumberStyles.AllowDecimalPoint | NumberStyles.AllowCurrencySymbol);
 
The enumeration also provides some useful combinations of styles as named values. The example above used two styles to allow the conversion of a currency value. We can use the Currency value of the NumberStyles enumeration to permit these styles and more.
 
// Conversion of a currency value float money = float.Parse(“£9,999.99”, NumberStyles.Currency);
 
Available Number Styles
 
The full list of available number styles is as follows:
 
Number Styles Description Example
AllowCurrencySymbol The string may include a currency symbol.  The currency symbol permitted is determined by the user’s local configuration settings. “£1500”
AllowDecimalPoint The string may include a single decimal point “1500.00”
AllowExponent The string may be a number expressed using exponential notation. “1.5E3”
AllowHexSpecifier The string may contain a hexadecimal number only. “5DC”
AllowLeadingSign The string may include a leading sign indicating a positive or negative number.  The sign symbols permitted are determined by the user’s local configuration settings. “-1500”
AllowLeadingWhite The string may include leading whitespace characters including true spaces and some control characters (Unicode characters 9 to 13). ”  1500″
AllowParentheses The string may include a single pair of parentheses around the number.  If the parentheses are present, the number is determined to be negative. “(1500)”
AllowThousands The string may include thousands separators.  The separator symbol permitted is determined by the user’s local configuration settings. “1,500”
AllowTrailingSign The string may include a trailing sign indicating a positive or negative number.  The sign symbols permitted are determined by the user’s local configuration settings. “1500-“
AllowTrailingWhite The string may include trailing whitespace characters. “1500  “
Any The string may contain any combination of the above “Allow” number styles except for the use of hexadecimal numbers. “1.5E3-“
Currency The string may contain any combination of the above “Allow” number styles except for the use of hexadecimal numbers or exponential notation. “(£1,500.00)”
Float Provides a combination of the AllowDecimalPoint, AllowExponent, AllowLeadingSign, AllowLeadingWhite and AllowTrailingWhite number styles. “-1,500.00”
HexNumber Provides a combination of the AllowHexSpecifier, AllowLeadingWhite and AllowTrailingWhite number styles. ” 5DC “
Integer Provides a combination of the AllowLeadingSign, AllowLeadingWhite and AllowTrailingWhite number styles. ”  -1500″
None The string may include none of the “Allow” number styles. “1500”
Number Provides a combination of the AllowDecimalPoint, AllowLeadingSign, AllowLeadingWhite, AllowThousands, AllowTrailingSign and AllowTrailingWhite number styles. ” -1,500.00 “
 
Internationalization
 
The .NET framework includes a large amount of functionality relating to internationalization in code. This simply means developing your software to function for all users in any part of the world using their local settings for numbers, currencies, languages, etc.
 
This is a complex subject and beyond the scope of a tutorial for C# language basics. Generally speaking for numeric conversions you can use the above number styles to use local settings.
 
Converting Numeric Values To String Data
 
Previously, we had described the process of converting strings into numeric data. This is particularly of use when accepting numeric input from a user. In a similar way, it is important to be able to convert numeric data to string information when outputting to screen, printer, disk or other devices. This is because much of the output functionality provided by the .NET framework requires the use of strings.
 
ToString Method
 
Every data type and class definition provided by the .NET framework includes a method named ToString. This method returns a string representation of the value or object that the method is executed against. Some classes generate objects that are not easily represented as a string and in these cases the ToString method generally returns the class’ fully qualified name; that is the namespace and name together.
 
For example:
 
object anObject = new object();
Console.WriteLine(anObject.ToString());     // Outputs "System.Object"
 
Basic Numeric Conversion Using ToString
 
The simplest method to convert numeric data values to strings is to use to ToString() method for the data type with no parameters specified. The string produced then contains the number with no formatting applied. This method can be applied on both variables and literal values.
 
int quantity = 1500;
float price = 1.50F;

Console.WriteLine(quantity.ToString());            // Outputs "1500"
Console.WriteLine(price.ToString());               // Outputs "1.5"
Console.WriteLine(sold.ToString());                // Outputs "True"
 
Formatting Converted Numbers
 
The basic conversion of numeric data to strings described above is useful but when displaying values to your application’s user you should format the numbers appropriately for their purpose and according to the local settings of the user’s environment. The ToString method permits the programmer to add format specifiers that provide this formatting. The format specifiers are supplied as a string parameter to the ToString method.
 
int quantity = 1500;
float price = 1.50F;
float discount = 0.05F;

Console.WriteLine(quantity.ToString("n0"));        // Outputs "1,500"
Console.WriteLine(price.ToString("c"));            // Outputs "£1.50"
Console.WriteLine(discount.ToString("p1"));        // Outputs "5.0 %"
 
The three specifiers used in the above example provide fixed point notation (n), currency notation (c) and percentage type notation (p) formatting. In the case of the fixed point and percentage specifier a number is included as a suffix. This is called the precision specifier and is used to modify the behaviour of the format specifier.
 
Available Format Specifiers
 
The full list of available format specifiers and the effect of the precision specifier for each is as follows:
 
Specifiers Description Effect of Precision Specifiers
C or c Formats the number as a monetary value including the correct number of decimal places and the appropriate currency symbol for the user’s local setting Specifies a fixed number of decimal places.
D or d Formats integers only as simple whole numbers.  Specifies the minimum number of digits.  Leading zeroes are added if required.
E Formats numbers using exponential notation.  The resultant string includes an upper case letter ‘E’. Specifies a fixed number of decimal places for the mantissa.  If omitted, six decimal places are used.
e Formats numbers using exponential notation.  The resultant string includes a lower case letter ‘e’. Specifies a fixed number of decimal places for the mantissa.  If omitted, six decimal places are used.
F or f Formats numbers using fixed point notation. Specifies a fixed number of decimal places.
G or g Formats numbers using either exponential or fixed point notation, whichever produces the shortest string.  The actual results vary according to the data type being converted and whether a precision specifier is used. See ‘e’, ‘E’ and ‘F or f’.
N or n Formats numbers using fixed point notation with thousands separators. Specifies a fixed number of decimal places.
P or p Formats numbers using percentage notation.  For example, 0.25 is formatted as 25%. Specifies a fixed number of decimal places.
R or r Formats numbers using Round-Trip Format.  This is a special format that ensures that the string generated can be converted back to the original number using Parse methods. Unused.
X Converts numbers into a string representation of their hexadecimal value.  The digits 0 to 9 and A to F are used. Specifies the minimum number of digits.  Leading zeroes are added if required.
x Converts numbers into a string representation of their hexadecimal value.  The digits 0 to 9 and a to f are used. Specifies the minimum number of digits.  Leading zeroes are added if required.
 
Using Picture Formats for Custom Formatting
 
The standard format specifiers are useful in most situations, particularly when your application is being used around the world and must use the user’s local settings for display of values.
 
However, there may be some circumstances where the format specifiers do not provide the desired results. In these cases, it is possible to use a picture format. This is a format string that specifies custom formatting for numeric to string conversion.
 
A picture format is a string containing special characters that affect the final conversion. There are a number of available control characters; each will be considered in the following sections:
 
Zero Placeholder
 
The zero placeholder digits ((zero in numeric (0))) in a custom picture format indicate that a digit is required in the resultant converted string. If there is a digit in the original number at the position of the placeholder digit then this digit is copied to the final output. If there is no digit at this position then a zero is used instead.
 
This allows the generation of leading zeroes. If the integer part of a number being converted is longer than the number of placeholder digits then the extra digits will be included to avoid truncation. Digits following the decimal point can be rounded however.
 
int small = 12;
int large = 123456;
float tiny = 1.234F;

Console.WriteLine(small.ToString("0000"));         // Outputs "0012"
Console.WriteLine(large.ToString("0000"));         // Outputs "123456"
Console.WriteLine(tiny.ToString("0000"));          // Outputs "0001"
 
Decimal Point Placeholder
 
The second special character is the decimal point placeholder. This can be combined with the zero placeholder to identify the number of digits required both before and after a decimal point. Although the decimal point placeholder character is always a full-stop or period character (.), the actual character in the resultant string is dependant upon the user’s local settings.
 
int small = 12;
double large = 123456.789;
float tiny = 1.234F;

Console.WriteLine(small.ToString("00.00"));      // Outputs "12.00"
Console.WriteLine(large.ToString("00.00"));      // Outputs "123456.79"
Console.WriteLine(tiny.ToString("00.00"));       // Outputs "01.23"
 
Digit Placeholder
 
The digit placeholder (#) character is similar to the zero placeholder. It defines the position of a digit within the resultant formatted string and causes rounding after the decimal point. However, the digit placeholder does not cause leading or trailing zeroes to be added to a number where the original numeric value has no digit in the appropriate position.
 
int small = 12;
double large = 123456.789;
float tiny = 1.234F;

Console.WriteLine(small.ToString("##.##"));     // Outputs "12"
Console.WriteLine(large.ToString("##.##"));     // Outputs "123456.79"
Console.WriteLine(tiny.ToString("##.##"));      // Outputs "1.23"
 
The digit placeholder has a strange side-effect when converted a zero value to a string. As the placeholder will not cause the creation of either leading or trailing zeroes, when converting a zero value the resultant string is empty. This can be very useful in circumstances where showing zero values is not desirable.
 
Console.WriteLine(0.ToString(“##.##”)); // Outputs an empty string
 
Thousands Separator Placeholder
 
The thousands separator placeholder is represented as a comma (,). If a comma is included in the picture format to the left of any decimal point and between zero or digit placeholders then thousands separators are inserted into the resultant string. Although the thousands placeholder character is always a comma, the actual character in the resultant string is dependant upon the user’s local settings.
 
int small = 12;
double large = 123456.789;
float tiny = 1.234F;

Console.WriteLine(small.ToString("#,#.00"));    // Outputs "12.00"
Console.WriteLine(large.ToString("#,#.##"));    // Outputs "123,456.79"
Console.WriteLine(tiny.ToString("#,#.##"));     // Outputs "1.23"
 
Percentage Placeholder
 
The percentage placeholder (%) is used when displaying percentage values. The placeholder performs two actions. Firstly it identifies the position in the resultant string where the percentage symbol should appear. Secondly, it multiplies the value being converted by one hundred. Although the percentage placeholder character is always a percent symbol, the actual character in the resultant string is dependant upon the user’s local settings.
 
int small = 12;
double large = 123456.789;
float tiny = 0.0015F;

Console.WriteLine(small.ToString("#,#.#%"));  //Outputs "1,200%"
Console.WriteLine(large.ToString("#,#.#%"));  //Outputs "12,345,678.9%"
Console.WriteLine(tiny.ToString("#,#.#%"));   //Outputs ".2%"
 
Custom Exponential Notation
 
Picture formats can be used to generate custom scientific or exponential notation. There are several characters that can be used to determine the exact exponential notation formatting used. The first character that is always required is an upper case ‘E’ or a lower case ‘e’.
 
This indicates that exponential notation is to be used. This is then followed by one or more zeroes to indicate the minimum number of digits to display for the exponent. The mantissa formatting is controlled by the placeholder characters that appear before the letter ‘E’ or ‘e’.
 
int small = 12;
double large = 123456.789;
float tiny = 0.0015F;

Console.WriteLine(small.ToString("0.0E0"));      // Outputs "1.2E1"
Console.WriteLine(large.ToString("0.00e00"));    // Outputs "1.23e05"
Console.WriteLine(tiny.ToString("0.00E00"));     // Outputs "1.50E-03"
 
The exponential notation can be modified further by adding a plus or minus symbol directly after the letter. A plus symbol (+) indicates that the sign for the exponent value should always be included in the resultant string. A minus (-) indicates that the sign character should only appear for negative exponent values.
 
int small = 12;
double large = 123456.789;
float tiny = 0.0015F;

Console.WriteLine(small.ToString("0.0E-0"));      // Outputs "1.2E1"
Console.WriteLine(large.ToString("0.00e+00"));    // Outputs "1.23e+05"
Console.WriteLine(tiny.ToString("0.00E+00"));     // Outputs "1.50E-03"
 
Literal Characters
 
Often numeric values need to be formatted to include non-numeric characters. This can be achieved by inserting the characters into the picture format. To insert special characters such as those, described in the previous sections, enclosed them in apostrophes (‘) or quotes (“). For ease of reading, the following example uses apostrophes.
 
Console.WriteLine(12345.ToString("00-00-00"));   // Outputs "01-23-45"
Console.WriteLine(12345.ToString("0'E'"));       // Outputs "12345E"
 
Escape Characters
 
Escape characters may also be used in picture format strings. These use the standard backslash character to identify an escape sequence. This backslash must appear in the format string itself so must be inserted using a double-backslash if the picture format is not preceded by a ‘@’ character.
 
Note that to insert a backslash character into to final formatted string, four backslashes must be included in the picture format.
 
Console.WriteLine(123.45.ToString("\\'0.00\\'"));  //Outputs "'123.45'"
Console.WriteLine(12345.ToString("000\\\\000"));   //Outputs "012\345"
 
String.Format Method
 
The Format function is a static method of the String class. As mentioned earlier, a static method is one that can be called against the String class itself, rather than a method that requires a string object to be created first. The Format method allows the generation of strings that contain both textual information and inserted numeric data. This is ideal for outputting data for the user to read.
 
The Format method requires several parameters to operate correctly. The first parameter is always a template string. The template contains the text that is desired in the final string and one or more placeholders that are to be replaced with other values. The remainders of the parameters are the variables or literals that are to be formatted and inserted in place of the placeholders.
 
Note: The variables or literals can be of any data type including numeric data, strings and objects. Here, we will consider only numeric data.
 
Templates and Placeholders
 
As described above, the template string must include placeholders to determine where other values are to be inserted. Each placeholder consists of a number between brace characters or curly brackets {}. The number in the braces is an index number that refers to one of the other parameters passed to the Format method. The index of the first non-template parameter is zero. A simple example can shown given below:
 
string output;
int selection = 5;

// Generate the output string
output = string.Format("You selected item {0} from the list.", selection);

Console.WriteLine(output);	 //Outputs "You selected item 5 from the list."
 
In the above example, the template string includes a single placeholder. The number between the braces is a zero, indicating that the first parameter after the template should be used as a replacement for the placeholder. In this case the value of the selection variable. However, the Format method is not limited to including only one parameter after the template. The following example shows two placeholders.
 
string output;
int selection = 5;
int count = 10;

// Generate the output string
output = string.Format("You selected item {0} from {1}.", selection, count);

Console.WriteLine(output);     //Outputs "You selected item 5 from 10."
 
Numeric Formatting
 
When we inserted numbers and want to convert into strings using the String.Format method, the numbers can be formatted. The formatting is achieved by adding format specifiers within the placeholders. The available format specifiers are the same as those for the ToString method of numeric data types. A table of all of the format specifiers is included in part 19 of the C# Fundamentals tutorial.
 
To include a format specifier, a colon (:) is inserted after the placeholder index number. The format specifier is then added before the closing brace. The following example shows the same parameter being used by two placeholders. One uses formatting, the other does not.
 
string output;
int value = 100;

// Convert a number to hexadecimal
output = string.Format("The decimal value {0} = {0:X} in hex.", value);

Console.WriteLine(output);   // Outputs "The decimal value 100 = 64 in hex."
 
Including Braces in Templates
 
In some circumstance you may require brace characters in the template string to be included in the output string. This is achieved by adding two brace characters. When a double brace is encountered by the Format method it is replaced by a single brace.
 
string output;
int value = 100;

// Convert a number to hexadecimal
output = string.Format("{{The decimal value {0} = {0:X} in hex.}}", value);

Console.WriteLine(output);   // Outputs "{The decimal value 100 = 64 in hex.}"
 
Console.WriteLine Method
 
Early in the C# Fundamentals tutorial the Console.WriteLine method was used to output some simple text in a console application. Console.WriteLine actually uses the same functionality as String.Format when generating the string that is to be outputted. This means that the above example can be greatly simplified as follows:
 
int value = 100;
// Convert a number to hexadecimal
Console.WriteLine("{{The decimal value {0} = {0:X} in hex.}}", value);
 
Trimming
 
Often a string that has been input by the user will include additional whitespace characters at the start or the end of the string. Sometimes the user may enter only whitespace where information is required and this must be tested for. In both cases, there is a need to remove excess whitespace characters from the string.
 
The String class provides three methods for removing whitespace. The TrimStart and TrimEnd methods remove whitespace from either the start or the end of a string. The Trim method combines the two functions by removing leading and trailing whitespace with a single call.
 
string inputted = "  BlackWasp  ";

Console.WriteLine(inputted.TrimStart());        //Outputs "BlackWasp  "
Console.WriteLine(inputted.TrimEnd());          // Outputs "BlackWasp"
Console.WriteLine(inputted.Trim());             // Outputs "BlackWasp"
 
Note: It is important to note that the Trim methods return a new string with whitespace removed. The original string is not affected by the operation.
 
string original = "  BlackWasp  ";
string trimmed = original.Trim();

Console.WriteLine(original);                    // Outputs "BlackWasp"  
Console.WriteLine(trimmed);                     // Outputs "BlackWasp"
 
Padding
 
The String class provides two methods for padding. This is almost the reverse action to trimming in that it adds spaces to the left or right of a string until the resultant string is of a specified length. This is useful when producing fixed-width columns of information where each column needs to be aligned to the left or right.
 
The PadLeft method adds spaces to the left of a string and the PadRight add them to the right. An integer parameter is used to indicate how long the resultant string should be. If the original string is longer than the parameter value indicates then the resultant string will be equal to the original string.
 
string value1 = "£1.00";
string value2 = "£10.00";
string value3 = "£100.00";

// Output a right-aligned column
Console.WriteLine(value1.PadLeft(8));           // Outputs "   £1.00"
Console.WriteLine(value2.PadLeft(8));           // Outputs "  £10.00"
Console.WriteLine(value3.PadLeft(8));           // Outputs " £100.00"

// Output a left-aligned column
Console.WriteLine(value1.PadRight(8));          // Outputs "£1.00   "
Console.WriteLine(value2.PadRight(8));          // Outputs "£10.00  "
Console.WriteLine(value3.PadRight(8));          // Outputs "£100.00 "

// Trying to pad a string that is too long
Console.WriteLine(value1.PadRight(3));          // Outputs "£1.00"
 
The padding functions can also be called with a second parameter. This parameter is a char value holding a single character that is used instead of the default whitespace padding character.
 
string value = "£1.00";

Console.WriteLine(value.PadLeft(8,'.'));        // Outputs "...£1.00"
Console.WriteLine(value.PadRight(8,'_'));       // Outputs "£1.00___"
 
Text Case Conversion
 
The last formatting functions to be considered in this article are the case conversion methods. The String class provides methods to allow a string to be converted to upper case or lower case text. These use the current local culture settings of the execution environment to ensure correct text conversion for various languages. The methods are named ToLower and ToUpper.
 
string webSite = "BlackWasp";

Console.WriteLine(webSite.ToLower());           // Outputs "blackwasp"
Console.WriteLine(webSite.ToUpper());           // Outputs "BLACKWASP"
 
String Concatenation
 
String concatenation is the act of combining two strings by adding the contents of one string to the end of another. Earlier in this chapter we considered string operations including using the concatenation operator (+). We used the following example:
 
string start = "This is a ";
string end = "concatenated string!";

string concat = start + end;    // concat = "This is a concatenated string!"
 
The String class also provides a method for concatenation of strings. This is the Concat method and it allows many strings to be passed as parameters. These strings are joined together and a new, concatenated string is returned. Note in the example that the Concat method is static and therefore is preceded by the class name, ‘string’. The lower case class name is used as this is C#. However, the .NET framework structure name could be substituted so you may often see String.Concat with a capital ‘S’.
 
string start = "This is a ";
string end = "concatenated string!";

string concat = string.Concat(start, end);
 
Note: As with previous string functions, the method returns the concatenated string but the original strings are not modified.
 
Inserting Strings into Strings
 
String concatenation is useful when joining two strings end to end. But, the String class also provides a method by which one string can be inserted into the middle of another. This function is very useful when using standard template strings that require insertion of text at specific points.
 
The Insert method acts upon an existing string variable or literal and requires two parameters. The first parameter is an integer that indicates the position where the second string is to be inserted. This integer counts characters from the left with zero indicating that the insertion will be at the beginning of the string. The second parameter is the string to be inserted.
 
string template = "Please ask for  on arrival.";
string tutor = "Ujjwal";

Console.WriteLine(template.Insert(15, tutor));

// Outputs: "Please ask for Ujjwal on arrival."
 
Removing Characters from a String
 
The Insert method has an opposite function in the Remove method. This method allows characters to be removed from a string. The characters are simply erased, shortening the string accordingly.
 
There are two overloads available for calling. The first requires a single parameter to indicate the start position for the character removal. The second overload adds a second parameter specifying how many characters to delete. Any further characters are unaffected.
 
string sample = "The quick brown fox jumps over the lazy dog.";

string result = sample.Remove(16);  // result = "The quick brown "
result = sample.Remove(16, 24);     // result = "The quick brown dog."
 
Extracting Text from a String
 
The String class provides a very useful function to extract a piece of text from the middle of an existing string. This method has two overloads that are very similar to those of the Remove method.
 
However, rather than removing the middle section of the string and keeping the start and end, the Substring method discards the start and end and returns the middle section. The following code illustrates this using the same parameters as the previous example.
 
string sample = "The quick brown fox jumps over the lazy dog.";

string result = sample.Substring(16);   // result = "fox jumps over the lazy dog."
result = sample.Substring(16, 24);      // result = "fox jumps over the lazy "
 
Search and Replace
 
All modern word processors and text editors include a search and replace function that permits a specified piece of text to be substituted with a second string. This functionality is actually provided by the .NET framework with the Replace method. The Replace method accepts two parameters.
 
The first is the string to search for and the second is the string to use as a substitute. When executed, all instances of the first parameter string are automatically replaced.
 
string sample = "The brown fox.";

string result = sample.Replace("brown", "red"));  // result = "The red fox."
 
Copying Strings
 
The final simple string manipulation function to be considered in this article is the static Copy method. This method simple creates a copy of an existing string. It provides the same functionality as assigning to a string directly.
 
string sample = "The brown fox.";

string result = string.Copy(sample);    // result = "The brown fox." ,
 
Equality and Inequality Operators
 
As earlier, we discussed that the equality (= =) and inequality (!=) relational operators. These operators allow an exact, case-sensitive comparison of two strings. In the case of the equality operator, if the strings match perfectly, the resultant Boolean value is true. If there is any difference between the two strings, the result is false. The inequality operator returns the opposite result. This was demonstrated with the following example:
 
string s1 = "String to compare.";
string s2 = "String to compare.";
string s3 = "String to Compare.";   // Note the capital 'C'
bool result;

result = s1 == s2;                  // result = true
result = s1 == s3;                  // result = false
result = s1 != s2;                  // result = false
result = s1 != s3;                  // result = true
 
These two operators are useful in many situations but do have some limitations. They do not allow the programmer to consider the equality of two strings that match in all but capitalisation or other cultural factors. They also do not include any concept of ordering that would allow the comparison to indicate that one string is greater than another. This article explains the various string comparison methods that are provided by the string class to solve these problems.
 
Relative Comparison
 
CompareTo Method
 
The .NET framework provides a method named CompareTo for many data types including strings and numeric types. This method allows to values to be compared and returns a result that indicates not only if they are equal but also which value is the greater when they are not equal.
 
The method considers cultural information when judging which of the strings are equal. For example, Japanese katakana characters can be written in two ways, half-width or full-width. The CompareTo method considers characters written as full-width to be equal to the same characters as half-width. The same cultural information is used to determine which of the strings is the greater.
 
The CompareTo method operates against an existing string. The string that it is to be compared against is passed as the only parameter. The method returns an integer indicating the result of the relative comparison as follows:
 
Return Value Meaning
Zero The two strings are equal.
Less than Zero The first string has a value that is less than the second.
More than Zero The first string has a value that is greater than the second or the second string is undefined (null).
 
This can be clarified with this example:
 
string animal1 = "Cat";
string animal2 = "Dog";
int result;

result = animal1.CompareTo("Cat");       // result is zero
result = animal2.CompareTo("Cat");       // result is greater than zero
result = animal1.CompareTo(animal2);     // result is less than zero
 
Note: As this method is called against an existing string instance, if the string is null then an exception occurs.
 
string animal = null;
int result;

result = animal.CompareTo("Cat");           // Causes an exception
 
Compare Method
 
The Compare function is a static method of the string class. This method provides similar functionality to CompareTo but allows more options to be specified. As a static member of the string class, the two strings to be compared are both passed as parameters.
 
string animal1 = "Cat";
string animal2 = "Dog";
int result;

result = String.Compare(animal1, "Cat");    //result is zero
result = String.Compare(animal2, "Cat");    //result is greater than zero
result = String.Compare(animal1, animal2);  //result is less than zero
 
Null Comparison
 
As described in the previous section, the CompareTo method raises an exception if the string that is being tested is null. This is because the null object assigned to the string has no available methods. However, as the Compare method is static, and therefore does not require an object instance, null strings can be compared.
 
string animal = "Cat";
int result;

result = String.Compare(animal, null);      // result is greater than     zero
result = String.Compare(null, animal);      // result is less than zero
result = String.Compare(null, null);        // result is zero
 
Case Sensitivity
 
The Compare method allows the programmer to decide whether to perform case-sensitive or case-insensitive comparisons. The differentiation between upper case and lower case lettering is applied according to the rules of the user’s local language settings.
 
To determine whether to use case-sensitive comparison a Boolean value is supplied as a third parameter. If the value is true then character casing is ignored. If the parameter is set to false then the effect is the same as not supplying the parameter at all; the test is case-sensitive.
 
string animal1 = "Cat";
string animal2 = "cat";                      // Note use of lower case
int result;

result = String.Compare(animal1, animal2, true);   // Strings are equal
result = String.Compare(animal1, animal2, false);  // Strings are not equal
 
The Compare method includes several other overloaded variations allowing the comparison of strings using further control of international language settings, as well as facilities for comparing only parts of strings.
 
CompareOrdinal Method
 
The next method for string comparison to be considered is the CompareOrdinal method. This is a static method of the string class that allows a case-sensitive comparison of two strings. It differs from the Compare method in that the comparison result is based upon the numeric Unicode values for each character compared.
 
As the importance of characters in a cultural context can be different to the fixed numeric ordering of Unicode, different results may occur when comparing using this method. This is shown in the following example:
 
string animal1 = "Cat";
string animal2 = "cat";                       // Note use of lower case
int result;

result = String.Compare(animal1, animal2);  	//result is greater than zero
result = String.CompareOrdinal(animal1, animal2);   // result is less than zero
 
Equals Method
 
The Equals method of the string class is included here for completeness. This method returns a simple Boolean result indicating if two strings contain the same value. It provides similar functionality to the equality operator (= =). The method can be used against a string object with a single parameter or as a static member with two parameters for the strings to be compared.
 
string animal = "Cat";
bool result;

result = animal.Equals("Cat");                      // result = true
result = animal.Equals("cat");                      // result = false
result = String.Equals(animal, "Cat");              // result = true
result = String.Equals(animal, "cat");              // result = false
 
.NET 2.0 IsNullOrEmpty Method
 
Sometimes it’s necessary to check if a string is either empty or is undefined (null). Using .NET 1.1, this would require two tests. The .NET framework 2.0 introduces a new static method of the string class, called IsNullOrEmpty, which performs both tests with a single line of code. The method simply returns a Boolean value that is true when the string is either empty or null.
 
string animal1 = "Cat";
string animal2 = "";
string animal3 = null;
bool result;

result = String.IsNullOrEmpty(animal1);             // result = false
result = String.IsNullOrEmpty(animal2);             // result = true
result = String.IsNullOrEmpty(animal3);             // result = true
 
Retrieving a String’s Length
 
It is often required to check the length of a string, mostly to validate a user’s input. Fortunately the String class provides a property named Length that gives us this information. The property returns an integer value that represents the number of characters in the string.
 
string animal = "Dog";
int result;

result = animal.Length;                     // result is 3
result = "Elephant".Length;                 // result is 8
 
Note: The Length property is a very efficient method to execute. For this reason, when checking if a string is empty, it is more efficient to compare the length of the string with zero than to compare the string value itself to String.Empty or “”.
 
Locating Text within a String
 
Earlier in this C# tutorial we examined The use of the Substring method that allows the extraction of a number of characters from a specified position in a string. The reverse of this functionality is to specify a series of characters and identify the position at which that sub-string appears within a string. This can be achieved with the IndexOf and LastIndexOf methods.
 
The IndexOf method takes a parameter containing a sequence of characters to search for. If this sub-string exists within the main string then the position of the first occurrence is returned. This position is known as the index and is an integer value indicating the number of characters between the start of the string and the first character of the sub-string.
 
If the search term is found at the beginning of the string then the index value is zero. Should the sub-string not exist within the main string then the method always returns -1.
 
The LastIndexOf method operates in a similar manner to IndexOf. However, instead of returning the index of the first occurrence of the search term, LastIndexOf returns the position of the last occurrence. This is still an index value counted from the left of the string.
 
string phrase = "The quick brown fox jumps over the lazy dog.";
int result;

result = phrase.IndexOf("brown");           // result is 10
result = phrase.LastIndexOf("dog");         // result is 40
result = phrase.IndexOf("green");           // result is -1
result = phrase.LastIndexOf("blue");        // result is -1
 
Specifying a Limited Search
 
The IndexOf and LastIndexOf methods can be limited further by specifying the start position from which to search. In the case of the IndexOf method only occurrences of the specified sub-string at or to the right of this position will be matched. When using LastIndexOf, only matching sub-strings to the left of this position are located.
 
string phrase = "The quick brown fox jumps over the lazy dog.";
int result;

result = phrase.IndexOf("he");              // result is 1
result = phrase.IndexOf("he", 1);           // result is 1
result = phrase.IndexOf("he", 2);           // result is 32
result = phrase.LastIndexOf("he");          // result is 32
result = phrase.LastIndexOf("he",33);       // result is 32
result = phrase.LastIndexOf("he",32);       // result is 1
 
The search can be limited further with a third parameter. This parameter is an integer value that indicates the maximum number of characters from the start position that may be examined. If a match does not exist within the range of characters then the result returned is the same as if no match exists at all, -1.
 
string phrase = "The quick brown fox jumps over the lazy dog.";
int result;

result = phrase.IndexOf("brown");           // result is 10
result = phrase.IndexOf("brown", 5, 4);     // result is -1
result = phrase.LastIndexOf("fox");         // result is 16
result = phrase.LastIndexOf("he", 25, 5);   // result is -1
 
Simple Container Tests
 
The IndexOf and LastIndexOf methods are very useful when determining the exact position of search terms within strings. However, sometimes it is enough to simply know whether a sub-string exists or not. The String class provides several methods to perform this type of test.
 
StartsWith and EndsWith
 
The StartsWith and EndsWith methods allow the developer to determine if a string starts or ends with a specific series of characters. Both methods accept a single parameter for the sub-string to match, and both return a Boolean value indicating the result. These methods are case-sensitive.
 
string phrase = "The quick brown fox jumps over the lazy dog.";
bool result;

result = phrase.StartsWith("The quick");    // result is true
result = phrase.StartsWith("lazy dog.");    // result is false
result = phrase.EndsWith("lazy dog.");      // result is true
result = phrase.EndsWith("The quick");      // result is false
 
.NET 2.0 Contains Method
 
The final string function to consider in this article is the Contains method. Microsoft introduced this method in version 2.0 of the .NET framework. It operates in a similar manner to StartsWith and EndsWith but checks if the specified search term exists at any position within the main string.
 
string phrase = "The quick brown fox jumps over the lazy dog.";
bool result;

result = phrase.Contains("brown fox");      // result is true
result = phrase.Contains("lazy fox.");      // result is false
 
Practical Example(Enum):
 
testEnum.cs
 
using System;
using System.Collections.Generic;
using System.Text;

namespace testEnum
{
    //declare enum
    public enum Volume
    {
        Low,
        Medium,
        High
    }

    class Program
    {
        static void Main(string[] args)
        {
            Volume myVol=new Volume();
            string choice;
            for (int i = 1; i > 0; )
            {
                Console.WriteLine("1. Low");
                Console.WriteLine("2. Medium");
                Console.WriteLine("3. High");
                Console.WriteLine("Please enter your choice....");
                choice = Console.ReadLine();
                // create and initialize instance of enum type
                if (choice == "1")
                {
                    myVol = Volume.Low;
                    i++;
                }
                else if (choice == "2")
                {
                    myVol = Volume.Medium;
                    i++;
                }
                else if (choice == "3")
                {
                    myVol = Volume.High;
                    i++;
                }
                else
                {
                    Console.WriteLine("This is invalid choice." );
                    i = 0;
                    break;
                }

                // make decision based on enum value
                switch (myVol)
                {
                    case Volume.Low:
                        Console.WriteLine("The volume has been turned Down.");
                        break;
                    case Volume.Medium:
                        Console.WriteLine("The volume is in the middle.");
                        break;
                    case Volume.High:
                        Console.WriteLine("The volume has been turned up.");
                        break;
                }
                Console.ReadLine();
            } 
        }
    }
}
 
The output is:
 
img
 
Practical Example (Array):
 
testArray.cs
 
using System;
using System.Collections.Generic;
using System.Text;

namespace testArray
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] myIntArray;          // Declare the array.

            myIntArray = new int[11];   // Instantiate the array.

            for (int i = 0; i < 11; i++)   // Set the values.
                myIntArray[i] = i * 10;

            // Read and display the values of each element.
            for (int i = 0; i < 11; i++)
                Console.WriteLine("Value of element {0} = {1}", i, myIntArray[i]);
            Console.ReadLine();
        }
    }
}
 
The output is:
 
img