The characters or symbols that compose a CString variable are stored in an array of characters. To get to the character or symbol at a specific position, you can use the square brackets, the same way you would proceed for an array. This is possible because the square bracket operator is loaded for the CString class: TCHAR operator []( int nIndex ) const; Like an array, the characters of a CString value are stored in a 0-based index, meaning the first character is at index 0, the second at 2, etc. Imagine you have a string declared and initialized as: CString Capital(“Antananarivo”); To get the 5th character of this string, you could write: CString Fifth = Capital[4]; Here si an example: void CExerciseDlg::OnDraw(CDC* pDC) { CExerciseDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); CString Capital("Antananarivo"); CString Fifth = Capital[4]; pDC->TextOut(10, 20, Capital); pDC->TextOut(10, 40, Fifth); } Besides the square brackets, to access the character stored at a certain position in a string, you can call the GetAt(). Its syntax is: TCHAR GetAt( int nIndex ) const; Here is an example of using it: void CExerciseDlg::OnDraw(CDC* pDC) { CExerciseDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); CString Capital("Antananarivo"); CString Fifth = Capital.GetAt(4); pDC->TextOut(10, 20, Capital); pDC->TextOut(10, 40, Fifth); }
As stated already, a CString value is in fact an array of characters. This allows you to locate a position in the string and change its character. To do this, you can use the SetAt() method. Its syntax is: void SetAt(int nIndex, TCHAR ch); Here is an example: #include afxwin.h #include iostream using namespace std; int main() { CString Object("Wall"); cout "Object: " << (LPCTSTR)Object << endl; Object.SetAt(1, 'e'); cout << "Name: " << (LPCTSTR)Object << endl; return 0; }
Scanning a string consists of visiting or examining each one of its characters. One of the reasons you would do this is to look for a particular character that may be part of the string. To scan a string for a character, you can call the CString::Find() method. It is overloaded as follows: int Find(TCHAR ch) const; int Find(TCHAR ch, int nStart) const; To look for a single character in the string, pass a character value or variable as argument. In this case, the string would be examined from the most left character to the right. If you want the scanning to start at a certain position instead of from the most left character, besides the character to look for, pass a second argument as nStart. If the character is found in the string, this method returns the position of its first occurrence. If you want the get the last occurrence of the character, call the ReverseFind() instead. Its syntax is: int ReverseFind(TCHAR ch) const; These two versions of the Find() method are used to find a particular character in a string. Alternatively, you can specify a group of characters and try to find, at least, any one of them in the string. This operation is performed using the FindOneOf() method. Its syntax is: int FindOneOf(LPCTSTR lpszCharSet) const; The lpszCharSet argument is passed as a string which is a group of characters in any order. If the compiler finds any character of the lpszCharSet argument in the string, it returns its position. If none of the lpszCharSet characters is in the string, this method returns –1.
Every time the user types a character in a text-based control, this is referred to as a keystroke. When performing data entry, even if the user presses two keys simultaneously (to enter an uppercase letter or to type a special character), only one character is entered at a time. You can find out what character the user had entered in your application using appropriate functions. Some functions are used to categorize the types of characters on the keyboard. The functions used for these validations are as follows:
Besides the CString::SetAt() method, you can also use the Replace() method to replace a character of the string with another character. The syntax of the Replace() method is: int Replace(TCHAR chOld, TCHAR chNew); The Replace() method replaces each occurrence of the chOld argument. Whenever it finds it, it replaces it with the chNew character. Sub Strings Introduction A sub string is a character or a group of characters that is part of another string. Therefore, to create a string, you must first have a string as basis. When declaring and initializing a CString variable, although you can provide as many characters as possible, you may want the variable to actually hold only part of the string value. Based on this, to create a sub string when declaring a CString variable, you can use the following constructor: CString(LPCTSTR lpch, int nLength); When using this constructor, provide the whole string as a the null-terminated lpch string. To specify the number of characters for the sub string variable, provide an integer value for the nLength argument. Here is an example: void CExerciseDlg::OnDraw(CDC* pDC) { CExerciseDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); CString CofV = "Commonwealth of Virginia"; CString Sub(CofV, 12); pDC->TextOut(10, 20, Sub); } As you may realize from this constructor, its sub string is built from the left side of the string and starts counting characters towards the right. Once it reaches the nLength number of characters, it creates the new string and ignores the characters beyond nLength. If the string has already been initialized and you want to create a sub string made of some characters from its left side, you can call the CString::Left() method. Its syntax is: CString Left(int nCount) const; This method starts counting characters from the left to nCount characters and returns a new string made of those nCount characters. Here is an example: void CExerciseDlg::OnDraw(CDC* pDC) { CExerciseDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); CString Common = "Commonwealth of Virginia"; CString Sub = Common.Left(12); pDC->TextOut(10, 20, Sub); } As the Left() method considers the characters from the left position, if you want the characters of the end of a string, you can call the CString::Right() to create a new string. Its syntax is: CString Right(int nCount) const; Here is an example: void CExerciseDlg::OnDraw(CDC* pDC) { CExerciseDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); CString Common = "Commonwealth of Virginia"; CString Sub = Common.Right(8); pDC->TextOut(10, 20, Sub); } Alternatively, you can create a sub string using any range of characters from a string. To do this, call the CString::Mid() method whose syntaxes are: CString Mid(int nFirst) const; CString Mid(int nFirst, int nCount) const; To create the sub string start from any character in the string, use the first version whose nFirst argument specifies where the new string would start. In this case, the method would return a string made of characters from the nFirst position to the last character of the string. To create a sub string using a specific number of characters, use the second version. The nFirst argument specifies where the new string would start. The nCount argument is the number of characters that would be used from the main string to create the new string. Finding a Sub String To scan a string for a group of characters, you can call the following versions of the CString::Find() method: int Find(LPCTSTR lpszSub) const; int Find(LPCTSTR pstr, int nStart) const; To find a sub string in a string, pass the desired sub string as the lpszSub argument. As done with the single character, you can specify the position to start looking by providing a second argument as nStart and use the fourth version of this method. If the sub string is found, this method returns the position of its first character in the string. If the character or the sub string is not found, the method returns –1. Character and String Removal Besides the CString(LPCTSTR lpch, int nLength) constructor, the Left(), the Mid(), and the Right() method, another technique you can use to create a sub string consists of deleting characters from an existing string. This can be done by calling the CString::Delete() method. Its syntax is: int Delete(int nIndex, int nCount = 1); The nIndex argument specifies the first character of the range. If you pass only this argument, only the character at position nIndex will be deleted. If you want to delete more than one character, pass the desired number as the nCount argument. If the value of nCount is higher than the remaining number of characters from nIndex position, all characters to the right will be deleted. If you want to remove all occurrences of a particular character in a string, you can call the Remove() method. Its syntax is: int CString::Remove(TCHAR ch); This method scans the string looking for the ch character. Whenever it finds it, it deletes it. This operation is performed using case sensitivity. This means that only the exact match with case of ch would be deleted. Replacing String Occurrences Besides the CString::SetAt() method, you can also use the Replace() method to replace a character of the string with another character. The syntaxes of the Replace() method are: int Replace(TCHAR chOld, TCHAR chNew); int Replace(LPCTSTR lpszOld, LPCTSTR lpszNew); The Replace() method replaces each occurrence of the chOld argument. Whenever it finds it, it replaces it with the chNew character. Here is an example: void CExerciseDlg::OnMsgBox() { // TODO: Add your control notification handler code here CString Msg("The name you entered is not in our records.\n" "If you think there is a mistake, please contact HR.\n" "You can also send an email to humanres@functionx.com"); Msg.Replace("HR", "Human Resources"); Msg.Replace(".com", ".net"); MessageBox(Msg, "Failed Logon Attempt"); }
The sprintf() function we reviewed earlier is provided by the C/C++ language. The CString class provides its own function for formatting a string. This is done using the CString::Format() whose syntax are: void Format(LPCTSTR lpszFormat, ...); void Format(UINT nFormatID, ...); The lpFormat argument follows the exact same rules as the second argument to the sprintf() function seen earlier. The nFormatID argument is an identifier that can have been created using the String Table The third and subsequent arguments follow the same rules as the … argument of the sprintf() function. There are many examples of the CString::Format() method in our lessons. While the sprintf() function and the CString::Format() methods follow the order of the %Character combinations to format a message, the CString class provides a method that can also be used to format a string but it allows you to list the parameters if the order of your choice. Here is an example: void CExerciseDlg::OnMsgBox() { // TODO: Add your control notification handler code here const char *DeptToContat = "Human Resources"; const char EmailContact[] = "humanres@functionx.net"; const int StartShift = 8; const int EndShift = 6; CString Msg; Msg.Format("The name you entered is not in our records.\n" "If you think there is a mistake, please contact %s " "every week day from %d AM to %d PM.\n" "You can also send an email to %s", DeptToContat, StartShift, EndShift, EmailContact); MessageBox(Msg, "Failed Logon Attempt"); }
The constructors we have used so far were meant to initialize a string when declaring it. Normally, if you do not have an initial value when declaring the string variable, you can use the default constructor: CString(); The default constructor is used to declare an empty string that can be initialized later on. If the variable already contains a value but you want it to be empty, you can call the CString::Empty() method. Its syntax is: void Empty(); This method removes all characters, if there are any, from a string variable and restores the memory it was using. If you think the string contains empty spaces to its left side and you think this could compromise an operation on the string, to remove such empty spaces, call the TrimLeft() method whose syntax is: void TrimLeft(); To remove empty spaces from the right side of a string, call the TrimRight() method. Its syntax is: void TrimRight(); If at one time you want to find out whether a string is empty or not, call the CString::IsEmpty() method. Its syntax is: BOOL IsEmpty() const This method returns TRUE if the string is empty. Otherwise, it returns FALSE. String Assignment We saw earlier that you can declare an empty CString variable using the default constructor. To initialize it, you can assign it a string value of your choice. Here is an example: void CExoView::OnDraw(CDC* pDC) { CExoDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); CString Term = "Information Superhighway"; pDC->TextOut(20, 22, Term); }
Making a copy of a string consists of providing its value to another string. If you already have a CString initialized and you want to copy its value into another CString variable, you can use the following constructor: CString(const CString& stringSrc); This constructor is used to declare a CString variable and provide it with the value of another CString variable. Here is an example: void CExerciseDlg::OnDraw(CDC* pDC) { CExerciseDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); CString Term = "Information Superhighway"; CString Description(Term); pDC->TextOut(20, 22, Description); }
In US English, the following alphabetical letters are referred to as lowercase a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z. Their equivalents in uppercase are A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z. The digits 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, and the other characters are considered “as is”. To convert a lowercase CString variable to uppercase, you can call the MakeUpper() method. Its syntax is: void MakeUpper(); When executed, this method would examine each character of the string. If a character is a lowercase letter, it would be converted to uppercase. If a character is already in uppercase, it be left in uppercase. If the character is not a letter, it would be left intact. On the other hand, to convert the characters of a string to lowercase, call the MakeLower() method. Its syntax is: void MakeLower(); If a character is an uppercase letter, it would be converted to lowercase. If a character is already in lowercase, it be left in lowercase. The digits and other characters are left “as is”.
String comparison consists of finding out whether the values of two strings are identical or not. Toperform such a comparison, the CString class provides the Collate() method. Its syntax is: int Collate(LPCTSTR lpsz) const; The string that called this method is compared with the lpsx argument, character by character and with regards to the case of each combination of characters. To perform the comparison, this method refers to the Regional Settings of Control Panel on the user's computer concerning the numeric, the date, the time, and the currency systems used. The comparison starts with the left character for most Latin languages, including US English:
void CExerciseDlg::OnDraw(CDC* pDC) { CExerciseDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); CString CS = "Charles Stanley"; CString AS = "charles Stanley"; int Result = CS.Collate(AS); if( Result > 0 ) pDC->TextOut(10, 20, "Charles Stanley is Higher than charles Stanley"); else if( Result == 0 ) pDC->TextOut(10, 20, "Charles Stanley and charles Stanley are equal"); else // if( Result < 0 ) pDC->TextOut(10, 20, "Charles Stanley is Lower than charles Stanley"); } Besides the Collate() method, the CString class provides the Compare() method to perform a case-sensitive comparison of characters of two strings. Its syntax is: int Compare(LPCTSTR lpsz) const; This method compares the character at a position x to the character at the same position x of the other, lpsz, string. The approach used to perform the comparisons is the same with the difference that the Compare() method does not refer the user's Regional Settings.
As seen above, the Collate() method considers the cases of characters during comparison and refers to the Regional Settings of the user. If you just want a simple comparison to find if two strings are identical regardless of the cases of their characters, you can call the CString::CollateNoCase() method. Its syntax is: int CollateNoCase(LPCTSTR lpsz) const; This member function considers that the alphabet is made of characters of a single case, implying that the character a is exactly the same as the character A. The other symbols and digits are considered “as is”. It proceeds as follows:
void CExerciseDlg::OnDraw(CDC* pDC) { CExerciseDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); CString CS = "Charles Stanley"; CString AS = "charles Stanley"; int Result = CS.CollateNoCase(AS); if( Result > 0 ) pDC->TextOut(10, 20, "Charles Stanley is Higher than charles Stanley"); else if( Result == 0 ) pDC->TextOut(10, 20, "Charles Stanley and charles Stanley are equal"); else // if( Result < 0 ) pDC->TextOut(10, 20, "Charles Stanley is Lower than charles Stanley"); }
Here is an example: void CExerciseDlg::OnDraw(CDC* pDC) { CExerciseDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); CString YS = "Jeremy Stanley"; CString IS = "Jeremie Andy"; int Result = YS.CollateNoCase(IS); if( Result > 0 ) pDC->TextOut(10, 20, "Jeremy Stanley is Higher than Jeremie Stanley"); else if( Result == 0 ) pDC->TextOut(10, 20, "Jeremy Stanley and Jeremie Stanley are equal"); else // if( Result < 0 ) pDC->TextOut(10, 20, "Jeremy Stanley is Lower than Jeremie Stanley"); } Alternatively, to perform case-insensitive string comparison on CString variables, you can use the CompareNoCase() method. Its syntax is: int CompareNoCase(LPCTSTR lpsz) const; The CompareNoCase() method does not refer to the user's Regional Settings when performing its comparison. Besides the CollateNoCase() and the CompareNoCase() methods, the CString class provides an easier and probably more familiar means of performing value comparisons. Character insensitive comparisons on CString variables can be performed using Boolean operators ==, !=, <, <=, >, >=. Any of these operators can be applied on two CString variables or a combination of a CString and a null-terminated string variables. The operators are overloaded as follows: BOOL operator ==( const CString& s1, const CString& s2 ); BOOL operator ==( const CString& s1, LPCTSTR s2 ); BOOL operator ==( LPCTSTR s1, const CString& s2 ); BOOL operator !=( const CString& s1, const CString& s2 ); BOOL operator !=( const CString& s1, LPCTSTR s2 ); BOOL operator !=( LPCTSTR s1, const CString& s2 ); BOOL operator <( const CString& s1, const CString& s2 ); BOOL operator <( const CString& s1, LPCTSTR s2 ); BOOL operator <( LPCTSTR s1, const CString& s2 ); BOOL operator >( const CString& s1, const CString& s2 ); BOOL operator >( const CString& s1, LPCTSTR s2 ); BOOL operator >( LPCTSTR s1, const CString& s2 ); BOOL operator <=( const CString& s1, const CString& s2 ); BOOL operator <=( const CString& s1, LPCTSTR s2 ); BOOL operator <=( LPCTSTR s1, const CString& s2 ); BOOL operator >=( const CString& s1, const CString& s2 ); BOOL operator >=( const CString& s1, LPCTSTR s2 ); BOOL operator >=( LPCTSTR s1, const CString& s2 ); These operators work exactly as you are used to dealing with conditional statements except that the operands must be string values. |
|
|||||||||||||||||||||||||||||||||||||||||||||||||||
|