C++ Chapter 6

 

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()

 

5
Average: 5 (1 vote)

Thanks for sharing those

marvickmonk's picture

Thanks for sharing those basic C++ program and informative for C++ learners...

reply

thanks, friend. do go on with your valuable asessments.

Good revision

Niti Sharma's picture

Good revision on C++ Topic Strings.

reply

thanks dear niti. i do value your opinion.