String Basics
We have already used string values:
cout << "Please enter a number: ";
A string variable is exactly the same thing as an array of characters. However, when we make the declaration:
char s[10];
the variable
s will only allow a string of length up to 9. The reason for this is that C++ needs to include one more character after the string for its own housekeeping.Strings may be thought of as partially filled arrays. C++ uses a marker, the null character, denoted by '\0', to indicate the end of the string.
Note:
A string is different from an array of characters in that the null character is at the end of the string.
Initializing string variables
You can initialize a string variable when you declare it:
char message[20] = "Hello world!";
The string that we assign to the string variable need not take up the entire length of the array. When you initialize a string variable you can omit the size and C++ will make it big enough to fit the word (plus one for the null character).
char a_string[] = "abc";
Initializing an array of characters
We may initialize an array of characters, that is not a string?
char some_letters[4] = {'a', 'b', 'c'};
This does not include a null character and the last cell in the array remains uninitialized.
Note that this is completely different from the following:
char a_string[4] = "abc";
This does have a null character in the last spot in the array.
Indexed entries for string variables
A string variable is an array so it has indexed entries like any other array:
char test_string[4] = "Hi!";
The individual cells have the following values:
test_string[0] -> 'H'
test_string[1] -> 'i'
test_string[3] -> '\0'
We can also manipulate this string just like we would an array
int index = 0;
while (test_string[index] != '\0')
{
test_string[index] = 'X';
index++;
}
Now the cells have the following values:
test_string[0] -> 'X'
test_string[2] -> 'X'
test_string[3] -> '\0'
Do not overwrite the null character. If you do, C++ will no longer be able to process the string. The reason is that the null character indicates where the string ends. If it is discarded, then the array is no longer a string but just an array of characters. Notice also, that code such as that above would no longer work (since we have lost the end-of-loop identifier).
Simple string program:
#include <iostream.h>
#include <ctype.h>
const int MAX_STR = 20;
char ask_yn(char question[]);
// Ask question to user and return y/n
void upper_case(char str[]);
// changes the letters in str to upper case
int main()
{
char word[MAX_STR];
do
{
cout << "Enter a string of < 20 char: ";
cin >> word;
upper_case(word);
cout << word << "\n\n";
} while ( ask_yn("Do you wish to repeat procedure? ") == 'y' );
return 0;
}
void upper_case(char str[])
{
int index = 0;
while (str[index] != '\0')
{
str[index] = toupper(str[index]);
index++;
}
}
char ask_yn( char question[])
{
char ans;
cout << question;
cin >> ans;
if (ans != 'n')
ans = 'y';
return ans;
}
Using = and == with strings
String values and string variables are not like values and variables of other data types and many of the usual operations do not work for strings.
char my_string[10];
my_string = "Hello";
The only time you can use = with strings is when you're declaring the string variable.
Predefined string functions
C++ has defined some useful string functions. To have access to them, you must include the header file
string.h (see page 595). This include directive provides the following four functions:e.g.
strcmp if strcmp(string1, string2)
cout << "The strings are NOT the same.";
else
cout << "The strings are the same.";
This is what we use instead of == on strings and string variables.
if strcmp(string1, "no")
cout << "So you want to continue?";
else
cout << "Goodbye!";
Note:
strcmp
returns a negative number if string1 is alphabetically lower than string2. otherwise strcmp returns a positive number. A returned value of 0 indicates that both strings are identical.#include <iostream.h>
#include <string.h>
int main()
{
char secret_word[21];
char answer[21];
bool win = false;
int cmp_result;
cout << "Please enter a secret word (no more 20 characters): ";
cin >> secret_word;
cout << "\nThe secret word has " << strlen(secret_word)
<< " letters.\n\n";
while (! win)
{
cout << "Enter a word: ";
cin >> answer;
cmp_result = strcmp(answer, secret_word);
if (cmp_result == 0)
win = true;
else if ( cmp_result < 0)
cout << "\t'" << answer << "' before the secret.\n\n";
else
cout << "\t'" << answer << "' after the secret.\n\n";
}
cout << "\n\tThat's it!\n\n";
return 0;
}
e.g.
strlen char word[20] = "Hello there!";
int size;
size = strlen(word);
The value of size is 12. The '\0' (null character) is not counted in the length of the string.
e.g.
strcpy char string1[20]="hello", string2[20]="bye";Hence
: string1 -> "bye" string2 -> "bye"String constants may be the second argument only.
strcpy(string1, "hi there!");
Hence:
string1 -> "hi there!"It will copy a string that is too large for the receiving string.
char short_string[3];
strcpy(short_string, "much too long!");
This will continue to fill memory locations after
short_string with characters. Always ensure that the receiving string is of the appropriate size.
e.g.
strcatchar name[20] = "CSC215 ";
strcat(name, " Programming");
Hence
: name -> "CSC215 Programming"Note: As for
strcpy, it does not check that the first argument is big enough to hold the values of both strings.
Defining string functions
The
strcpy and strcat problem occurs because strcpy and strcat are not defined to take an argument indicating the size of the string. The programmer is responsible for ensuring that the problem does not occur.Consider a function that performs string concatenation in a more robust way than
strcat. To do this we will supply a number that indicates the size of the first string.void stringCat(char front[], int front_size, const char back[])
{
int back_length = strlen(back);
int front_length = strlen(front);
int total_length = front_length + back_length + 1
int i;
// calculate how much we can copy
if (front_length + 1 >= front_size)
// the string is full
return;
else if (total_length > front_size)
// front too small, truncate back.
back_length = front_size - front_length - 1;
for (i=front_length; i<front_length+back_length; i++)
front[i] = back[i - front_length];
// don't forget the null character!
front[i] = '\0';
}