
Chapter Six
Strings
are stored as null (‘\0’) terminated character arrays.
For example, if :
Char a[] = {‘v’, ‘*’, ‘7’};
then:
a[0] = ‘v’; a[1] = ‘*’; a[2] = ‘7’
Thus,
char name[] = "INDIA";
is the same as
char name[6] = {‘I’, ‘N’, ‘D’, ‘I’, ‘A’, ‘\0’};
Thus a string of n characters is stored in an array of (n+1) size, the last one to provide for the terminator null.
The following code will illustrate the point:
#include <iostream.h>
void main()
{
char name[] = "INDIA";
if (name[5] == '\0')
cout << "Yes";
else
cout << "No";
}
Output:
Yes
The following code further reinforces the concept:
#include <iostream.h>
void main()
{
char name[] = {'A', 'B', '\0', 'C'};
cout << name << endl;
cout << name[3];
}
Output:
AB
C
The output of a string (cout << name) terminates at ‘\0’, and only "AB" is printed, although the next line output (cout << name[3]) shows that ‘C’ is stored in that position.
//to demonstrate the null terminator
#include <iostream.h>
#include <string.h>
void main()
{
char a[] = {'I', 'N', 'D', 'I', 'A'};
char b[] = "INDIA";
char c[] = {'A', 'B', '\0', 'C'};
char d[] = "AB";
/* strcmp() compares two strings */
if (strcmp(a, b) == 0) //if they match
cout << "EQUAL" << endl;
else
cout << "UNEQUAL" << endl;
if (strcmp(c, d) == 0) //if they match
cout << "EQUAL" << endl;
else
cout << "UNEQUAL" << endl;
}
Output:
UNEQUAL
EQUAL
Here we have used the library function
strcmp(s1, s2) to compare two strings.
The first output (comparison of strings char a[], char b[]) is UNEQUAL although both of them store the same characters. This is because the null is automatically inserted at the end position when a string "INDIA" is assigned to a character array char b[], whereas the char a[] does not end in null..
The second output (comparison of strings char c[], char d[])is EQUAL although the arrays char c[] and char d[] are not only of unequal size, but also store different characters. This is because a string is deemed to be terminated in null, and strcmp() disregards any characters after null.
This is important because while copying a string to another in reverse order, if the null is copied as the first character, C++ will treat it as a null string.
//A wrong program
//strlen(s) is a C++ library function
//to extract the length of a string (s)
#include <iostream.h>
#include <string.h>
void main()
{
char a[6] = "INDIA";
char b[6]; //to store reverse character
int i, j;
/* copying string a to string b in reverse order */
for (i = 0, j = 5; j>=0; i++, j--)
b[i] = a[j];
cout << a << " " << strlen(a);
cout << endl;
cout << b << " " << strlen(b);
}
Output:
INDIA 5
0
Why is not the reverse string output? It is because its length is zero. Why is its length zero? Because the last character of string in char a[] was ‘\0’, and this was copied as the first character in char b[], and C++ does not look after encountering null.
In order to get over this problem. we make the value initial of j in the loop as 4 (i.e., 5 - 1). Or better still, use the built-in function
strlen()-1. This function gives the length of a string without the terminating ‘\0’ (null). In any case we have to append the null thus: b[5] = ‘\0’; and our code stands as follows:
//To reverse a string
#include <iostream.h>
#include <string.h>
void main()
{
char a[6] = "INDIA";
char b[6]; //to store reverse character
int i, j;
/* copying string a to string b in reverse order */
for (i = 0, j = 4; j>=0; i++, j--)
b[i] = a[j];
b[5] = '\0'; //append null at the end
cout << a << " " << strlen(a);
cout << endl;
cout << b << " " << strlen(b);
}
Output:
INDIA 5AIDNI 5
The library function
strrev()
reverses a string.
//To reverse a string
#include <iostream.h>
#include <string.h>
void main()
{
char str[] = "EDUCATION";
cout << strrev(str);
}
Output:NOITACUDE
To check for palindrome, compare the original and reversed string as illustrated below.
#include <iostream.h>
#include <string.h>
void main()
{
char str[20]="";
char cpy[20] = "";
cout << "Enter a word ";
cin >> str;
strcpy (cpy, str); //keep a copy
strrev(str); //reverse the string
/* compare copy of original & reversed string */
if (strcmp (cpy, str) == 0) //if equal
cout << "Pallindrome";
else
cout << "Not a pallindrome";
}
Output:
Enter a word elephant
//entered by user
Not a palindrome
Enter a word malayalam
//entered by user
Pallindrome
Since a string is stored as a single dimension character array, an array of strings must be stored as a double dimension array. The following examples make it clear:
//program-3.05 To change case of an input character
#include <iostream.h>
#include <ctype.h>
void main()
{
char wd[][10]={"ASIA", "EUROPE", "AMERICA", "AUSTRALIA", "AFRICA"};
cout << wd[2];
}
Output:
America
Note that while declaring the array of continents as a double dimension of the form
wd[x][y], the first dimension (x) may be left blank, but the value of the second dimension (y) must be specified as one more than the longest word.
The function strcmp() may be used to sort an array of words in alphabetical order. It is based on the logic that strcmp(s1, s2) gives a value less than or greater than zero depending upon the difference in ASCII value of the first character that differs in the strings s1, s2. So if the value of strcmp(s1, s2) > 0 then we swap the positions of the strings s1, s2 using a third variable temp[]; it continues until the value of flag remains zero and does not change to 1, indicating that there has been no swapping and that the array is arranged in order.
//To arrange words in alphabetic order
#include <iostream.h>
#include <string.h>
void main()
{
char wd[][10]={"ASIA", "EUROPE", "AMERICA", "AUSTRALIA", "AFRICA"};
int i, flag = 0; char temp[10] = "";
do{
flag = 0; //initialize
for (i = 0; i <= 3; i++)
{
strcpy(temp, "");
if (strcmp(wd[i], wd[i+1]) > 0)
{
flag = 1; //not yet in alphabetic order
strcpy(temp, wd[i]);
strcpy(wd[i], wd[i + 1]);
strcpy(wd[i + 1], temp);
} //end of if-block
} //end of for loop
} while (flag == 1);
for (i = 0; i < 5; i++)
cout << wd[i] << endl;
}
Output:
Africa America Asia Australia Europe
(in separate lines)
It is important to note that
strcmp() is case-sensitive, that is, "ABC" and "abc" will not be equal. The function strcmpi()
is used when we want to compare strings ignoring the case.
#include <iostream.h>
#include <string.h>
void main()
{
char a[] = "ELEPHANT";
char b[] = "elephant";
if (strcmp(a, b) == 0)
cout << "equal" << endl;
else
cout << "unequal" << endl;
if (strcmpi(a, b) == 0)
cout << "equal" << endl;
else
cout << "unequal" << endl;
}
Output:
Unequal
//using
strcmp()
Equal
//using
strcmpi()
//To separate words from a string
#include <iostream.h>
#include <string.h>
void main()
{
char a[] = "INDIA IS MY COUNTRY";
char b[10][10];
int j = 0, i = 0, k = 0;
for (k = 0; k <= strlen(a); k++)
{
b[j][i] = a[k]; //j-th word; i-th character
i++; //next character position
if (a[k] == ' '|| a[k] == '\0') //end of word / string
{
b[j][i] = '\0'; //word complete
i = 0; //start of new word
j++; // word count increase
} // end of if-block
} // end of for loop
cout << j << endl; //no. of words
for (k = 0; k < j; k++)
cout << b[k] << '\t';
} //end of main
Output:
4
INDIA IS MY COUNTRY
//To reverse each word in a sentence
#include <iostream.h>
#include <string.h>
void main()
{
char a[] = "INDIA IS MY COUNTRY";
char b[10][10];
int j = 0, i = 0, k = 0;
for (k = 0; k <= strlen(a); k++)
{
b[j][i] = a[k]; //j-th word; i-th character
i++; //next character position
if (a[k] == ' '|| a[k] == '\0') //end of word / string
{
b[j][i] = '\0'; //word complete
strrev(b[j]); //reverse the word
i = 0; //start of new word
j++;
} // word count increase
}
cout << j << endl; //no. of words
for (k = 0; k < j; k++)
cout << b[k] << '\t';
} //end of main
Output:
4
AIDNI SI YM YRTNUOC
In C++,
cin >> is not only the input operator. The problem in using cin >>
for strings is illustrated here.
You can win a million dollar award by writing the following QUIZ program, simply because no one will ever get the prize! Not even if they give the correct answer. See what is wrong.
#include <iostream.h>
#include <string.h>
void main()
{
char correct[] = "New Delhi";
char answer [10];
cout << "What is the capital of India? ";
cin >> answer;
if ( strcmp (correct, answer) == 0)
cout << "You win the prize!";
else
cout << "Sorry!";
}
Every time you run the program, no matter what answer you give, it appears hopeless!
To find what is wrong, add a line:
cout << answer;
The string stored in the
char answer[]
is New (and not New Delhi).
This is because
cin >>
reads only upto the white space (new line, tab or blank), and so it stores only the first word and ignores what comes after the blank.
To get over this problem, we will use
cin.getline()
to read strings.
So our modified quiz program stands thus:
#include <iostream.h>
#include <string.h>
void main()
{
char correct[] = "New Delhi";
char answer [10];
cout << "What is the capital of India? ";
cin.getline (answer, 10); //10 chars is the max limit
if ( strcmp (correct, answer) == 0)
cout << "You win the prize!";
else
cout << "Sorry!";
}
Now it works out beautifully!
There are other read methods like
cin.read() and cin.get(). The method cin.read() reads does not automatically append the mandatory terminating null character at the end of the string; whereas the method cin.get() will read like cin.getline()
but will not read the new line character, which remains in the buffer. This could create problems as shown below:
#include <iostream.h>
#include <string.h>
void main()
{
char name1[10], name2[10];
cout << "Enter your first name ";
cin.get(name1, 10);
cout << "Enter your surname ";
cin.get(name2, 10);
cout << name1 << " " << name2;
}
Output:
Enter your first name ABCD
//entered by user
Enter your surname ABCD
//output by computer
You don’t get a chance to respond to the second prompt, because it reads the new-line character already present in the buffer. This could be remedied by removing the character in the buffer with a character reading statement like
cin.get (char). But it will still cause a problem if there are more than one character in the buffer (for example, when the user types more than the maximum permissible length. The remaining characters entered for name1 will spill over and be assigned to name2
. This is illustrated below:
#include <iostream.h>
#include <string.h>
void main()
{
char name1[10], name2[10], ch;
cout << "Enter your first name ";
cin.get(name1, 10);
cin.get(ch); //attempt to remedy
cout << "Enter your surname ";
cin.get(name2, 10);
cout << name1 << " " << name2;
}
Output:
Enter your first name ABCDEFGHIJKL
//entered by user
Enter your surname ABCDEFGHI KL
// I assigned to
char, remaining part assigned to name2
.
So when there are several string inputs one after another, the best bet is
cin.getline()
Thanks for sharing those basic C++ program and informative for C++ learners...
thanks, friend. do go on with your valuable asessments.
Good revision on C++ Topic Strings.
thanks dear niti. i do value your opinion.