unit-5 c++ streams -...
TRANSCRIPT
1
UNIT-5
C++ Streams
-
Like the C-based I/O system, the C++ I/O system operates through
streams. A stream is a logical device that either produces or consumes information. A
stream is linked to a physical device by the I/O system. All streams behave in the
same way even though the actual physical devices they are connected to may differ
substantially. Because all streams behave the same, the same I/O functions can
operate on virtually any type of physical device. For example, you can use the same
function that writes to a file to write to the printer or to the screen. The advantage to
this approach is that you need learn only one I/O system.
The C++ Stream Classes
Standard C++ provides support for its I/O system in <iostream>. The
C++ I/O system is built upon two related but different template class hierarchies. The
first is derived from the low-level I/O class called basic_streambuf. This class
supplies the basic, low-level input and output operations, and provides the underlying
support for the entire C++ I/O system. The class hierarchy that you will most
commonly be working with is derived from basic_ios. This is a high-level I/O class
that provides formatting, error checking, and status information related to stream I/O.
(A base class for basic_ios is called ios_base, which defines several nontemplate traits
used by basic_ios.) basic_ios is used as a base for several derived classes, including
basic_istream, basic_ostream, and basic_iostream. These classes are used to create
streams capable of input, output, and input/output, respectively.
C++’s Predefined Streams
When a C++ program begins execution, four built-in streams are automatically
opened. They are:
Stream Meaning Default Device
cin Standard input Keyboard
cout Standard output Screen
cerr Standard error output Screen
clog Buffered version of cerr Screen
Streams cin, cout, and cerr correspond to C‟s stdin, stdout, and stderr.
2
By default, the standard streams are used to communicate with the console.
Formatted I/O
The C++ I/O system allows you to format I/O operations. For
example, you can set a field width, specify a number base, or determine how many
digits after the decimal point will be displayed. There are two related but conceptually
different ways that you can format data. First, you can directly access members of the
ios class. Specifically, you can set various format status flags defined inside the ios
class or call various ios member functions. Second, you can use special functions
called manipulators that can be included as part of an I/O expression.
Formatting Using the ios Members
When the left flag is set, output is left justified. When right is set,
output is right justified. When the internal flag is set, a numeric value is padded to fill
a field by inserting spaces between any sign or base character. If none of these flags
are set, output is right justified by default.
Eg:
#include <iostrearn>
using narnespace std;
int main()
cout.setf(ios: :showpoint)
cout.setf(ios: :showpos)
cout << 100,0; // displays +100.0
return 0;
It is important to understand that setf( ) is a member function of the ios
class and affects streams created by that class. Therefore, any call to setf( ) is done
relative to a specific. Instead of making multiple calls to setf( ), you can simply OR
together the values of the flags you want set. For example, this single call
accomplishes the same thing:
/ / You can OR together two or more flags cout.setf(ios: :showpoint, ios: :showpos)
3
Because the format flags are defined within the ios class, you must access
their values by using ios and the scope resolution operator. For example, showbase by
itself will not be recognized. You must specify ios::showbase.
Clearing Format Flags
The complement of setf( ) is unsetf( ). This member function of ios is
used to clear one or more format flags. The flags specified by flags are cleared. (All
other flags are unaffected.) The previous flag settings are returned.
Using width( ), precision( ), and fill( )
In addition to the formatting flags, there are three member functions defined
by ios that set these format parameters: the field width, the precision, and the fill
character.
The functions that do these things are width( ), precision( ), and fill( ), respectively.
By default, when a value is output, it occupies only as much space as the number of
characters it takes to display it. However, you can specify a minimum field width by
using the width() function. Its prototype is shown here:
streamsize width(streamsize w);
Here,w becomes the field width, and the previous field width is returned.
In some implementations, the field width must be set before each output. If it isn‟t, the
default field width is used. The streamsize type is defined as some form of integer by
the compiler.
After you set a minimum field width, when a value uses less than the specified
width, the field will be padded with the current fill character (space, by default) to
reach the field width. If the size of the value exceeds the minimum field width, the
field will be overrun. No values are truncated.
When outputting floating-point values, you can determine the number of
digits to be displayed after the decimal point by using the precision() function. Its
prototype is shown here:
4
streamsize precision(streamsize p);
Examples:
Cout.width(5);
Cout<<543;
Will produce the following width
5 4 3
Cout.precision(3);
Cout.3.1111;
Will produce
3.111 (truncated)
Cout.fill(„*‟);
Cout.width(5);
Cout<<456;
Will produce
* * 4 5 6
Cout.setf(ios::showpoint);
Cout.setf(ios::showpos);
Cout.precision(3);
Cout.width(5);
Cout<<1.2;
+ 1 . 2 0
Using Manipulators to Format I/O
The second way you can alter the format parameters of a
stream is through the use of special functions called manipulators that can be included
in an I/O expression.
5
Manipulator Purpose Input/Output
Endl Output a newline character Output
ends Output a null. Output
internal Turns on internal flag. Output
left Turns on left flag. Output
noshowpoint Turns off showpoint flag. Output
noshowpos Turns off showpos flag. Output
nouppercase Turns off uppercase flag. Output
resetiosfiags Turn off the flags
Input/Output
right Turns on right flag. Output
setfill(int ch) Set the fill character Output
setiosflags Turn on the flags
Input/output
setprecision Set the number of digits Output
setw(int w) Set the field width to w . Output
showbase Turns on showbase flag Output
showpoint Turns on showpoint flag. Output
showpos Turns on showpos flag. Output
Here is an example that uses some manipulators:
#include <iostrearm
#include <iomanip>
using narnespace std;
int main()
cout << setfill(‟?‟) << setw(10) ;
cout << 100 << endl;
This displays
???????100
6
As the examples suggest, the main advantage of using
manipulators instead of the ios member functions is that they commonly allow more
compact code to be written.You can use the setiosflags() manipulator to directly set
the various format flags related to a stream. For example, this program uses
setiosflags() to set the showbase and showpos flags:
#include <iostrearn>
#include <lomanip>
Int rnain()
cout << setiosflags(ios showpos);
cout << setiosflags(ios showbase);
cout << 123 ;
return 0;
The manipulator setiosflags( ) performs the same function as the member function
setf 0.
Designing our oun manipulators:
The general form of creating a manipulator without argument is
Ostream & manipulator (ostream output)
{
…………..
…………….(code)
……………
Return output;
}
The following function defines a manipulator called unit that displays inches
Ostream & unit(ostream & output)
{
Outout<<”inches”;
Return output;
}
The statement
7
Cout<<36<<unit;
Will produce the following output
36 inches
C++ File I/O
File Classes
To perform file I/O, you must include the header <fstream>
in your program. It defines several classes, including ifstream, ofstream, and fstream.
These classes are derived from istream, ostream, and iostream, respectively.
Remember, istream, ostream, and iostream are derived from ios, so ifstream,
ofstream, and fstream also have access to all operations defined by ios . Another class
used by the file system is filebuf, which provides low-level facilities to manage a file
stream.
The File Pointer
The file pointer is the common thread that unites the C I/O system. A file
pointer is a pointer to a structure of type FILE. It points to information that defines
various things about the file, including its name, status, and the current position of the
file. In essence, the file pointer identifies a specific file and is used by the associated
stream to direct the operation of the I/O functions. In order to read or write files, your
program needs to use file pointers. To obtain a file pointer variable, use a statement
like this:
FILE *fp
Opening and Closing a File
In C++, you open a file by linking it to a stream. Before you can
open a file, you must first obtain a stream. There are three types of streams: input,
output, and input/output. To create an input stream, you must declare the stream to be
of class if stream. To create an output stream, you must declare it as class ofstream.
Streams that will be performing both input and output operations must be declared as
8
class fstream. For example, this fragment creates one input stream, one output stream,
and one stream capable of both input and output:
if stream in; // input
of stream out; // output
fstrearn io; // input and output
Once you have created a stream, one way to associate it with
a file is by using openO. This function is a member of each of the three stream
classes. The prototype for each is shown here:
void ifstream::open(const char *fi1ename ,ios::openmode mode= ios::in);
void ofstream::open(const char *fi1ename, ios::openmode mode =ios::out
|ios::trunc);
void fstream::open(const char *filename, ios::openmode mode = ios::in |
ios::out);
Here,filename is the name of the file; it can include a
path specifier. The value of mode determines how the file is opened. It must be one or
more of the following values defined by openmode, which is an enumeration defined
by ios (through its base class los_base).
ios::app
ios::ate
ios::binary
ios::in
ios::out
ios::trunk
You can combine two or more of these values by ORing them together.
Including ios::app causes all output to that file to be appended to the end. This
value can be used only with files capable of output. Including ios::ate causes a seek to
the end of the file to occur when the file is opened. Although ios::ate causes an initial
seek to end-of-file, I/O operations can still occur anywhere within the file.The ios::in
value specifies that the file is capable of input. The ios::out value specifies that the file
is capable of output.
9
The ios::binary value causes a file to be opened in binary mode.
By default, all files are opened in text mode. In text mode, various character
translations may take place, such as carriage return/linefeed sequences being
converted into newlines. However, when a file is opened in binary mode, no such
character translations will occur. Understand that any file, whether it contains
formatted text or raw data, can be opened in either binary or text mode.. When
creating an output stream using ofstream, any preexisting file by that name is
automatically truncated.
The following fragment opens a normal output file.
ofstream out;
out.open(”test”, ios::out);
For ifstream, mode defaults to ios::in; for ofstream, and for
fstream, it is ios::in I ios::out. Therefore, the preceding statement will usually look
like this:
Out.open( test ) ;// defaults to output and normal file
If open() fails, the stream will evaluate to false when used in a
Boolean expression. Therefore, before using a file, you should test to make sure that
the open operation succeeded. Although it is entirely proper to open a file by using the
open() function, most of the time you will not do so because the ifstream, ofstream,
and fstream classes have constructor functions that automatically open the file. The
constructor functions have the same parameters and defaults as the open() function.
Therefore, you will most commonly see a file opened as shown here:
ifstream mystrearn( myfile ) // open file for input
As stated, if for some reason the file cannot be opened,
the value of the associated stream variable will evaluate to false. Therefore, whether
you use a constructor function to open the file or an explicit call to open( ), you will
want to confirm that the file has actually been opened by testing the value of the
stream.You can also check to see if you have successfully opened a file by using the
is_open( ) function, which is a member of fstream, ifstream, and ofstream. It has this
prototype:
10
bool is_opens;
It returns true if the stream is linked to an open file and false otherwise. For example,
the following checks if mystream is currently open:
To close a file, use the member function closcO. For
example, to close the file linked to a stream called mystream, use this statement:
mystrearn close();
The close() function takes no parameters and returns no value.
Writing a Character
The C I/O system defines two equivalent functions that
output a character: putc() and fputcO. (Actually, putc() is usually implemented as a
macro.) .The putc( ) function writes characters to a file that was previously opened for
writing using the fopen() function. The prototype of this function is
int putc(int ch, FILE *fr);
where fr is the file pointer returned by fopen() and ch is the character to be output.
The file pointer tells putc( ) which file to write to.If a putc( ) operation is successful, it
returns the character written. Otherwise, it returns EOF.
Reading a Character
There are also two equivalent functions that input a character: getc() and
fgetc( ). Both are defined to preserve compatibility with older versions of C. The getc(
) function reads characters from a file opened in read mode by fopenO. The prototype
of getc() is
in getc(FILE *fr);
where fr is a file pointer returned by fopen( ). The getc( ) function returns an EOF
when the end of the file has been reached. Therefore, to read to the end of a text file,
you could use the following code:
11
do
ch = getc(fp);
while(ch=EOF);
However, getc() also returns EOF if an error occurs. You can use ferror() to determine
precisely what has occurred.
Reading and Writing Text Files
It is very easy to read from or write to a text file. Simply use the <<
and >> operators the same way you do when performing console I/O, except that
instead of using cin and cout, substitute a stream that is linked to a file. For example,
this program creates a short inventory file that contains each item‟s name and its cost:
#include <iostream>
#include <fstrearm> using narnespace std;
Int main()
ofstream out(“inventory”) ; // output, normal file
if(out)
cout << “Cannot open inventory file.\n”;
return 1;
out << “Radios “F << 39,95 << endl; out << “toasters “ << 19.95 << endl;
out << “Mixers” << 24.80 << endl;
out.close()
return 0;
The following program reads the inventory file created by the previous
program and displays its contents on the screen:
#include <iostream>
#include <fstream> using narnespace std;
int main()
ifstream in(”inventory”); // input
12
if(in)
cout << “Cannot open inventory file.\n”;
return 1;
}
Char item[20];
Float cost;
In>>item>>cost;
Cout<<item<<cost;
In>>item>>cost;
Cout<<item<<cost;
In>>item>>cost;
Cout<<item<<cost;
In.close();
Return 0;
}
Random Access
In C++‟s I/O system, you perform random access by using the
seekg() and seekp() functions. Their most common forms are
istream &seekg(off_type offset, seekdir origin);
ostream &seekp(off_type offset, seekdir origin);
Here, off_type is an integer type defined by ios that is
capable of containing the largest valid value that offset can have. seekdir is an
enumeration defined by ios that determines how the seek will take place.
The C++ I/O system manages two pointers associated with a file.
One is the get pointer, which specifies where in the file the next input operation will
occur. The other is the put pointer, which specifies where in the file the next output
operation will occur. Each time an input or output operation takes place, the
appropriate pointer is automatically sequentially advanced. However, using the
seekg() and seekp() functions allows you to access the file in a nonsequential fashion.
13
The seekg( ) function moves the associated file‟s current get pointer offset number of
characters from the specified origin, which must be one of these three values:
ios::beg Beginning-of-file
ios::cur Current location
ios::end End-of-file
The seekp() function moves the associated file‟s current put pointer
offset number of characters from the specified origin, which must be one of the values
just shown.Generally, random-access I/O should be performed only on those files
opened for binary operations. The character translations that may occur on text files
could cause a position request to be out of sync with the actual contents of the file.
Obtaining the Current File Position
You can determine the current position of each file pointer by using these functions:
pos_type tellg
pos_type tellp
Here, pos_type is a type defined by ios that is capable of holding the largest
value that either function can return. You can use the values returned by tellg() and
tellp( ) as arguments to the following forms of seekg() and seekp( ), respectively.
istream &seekg(pos_type pos);
ostream &seekp(pos_type pos);
These functions allow you to save the current file location, perform other file
operations, and then reset the file location to its previously saved location.
I/O Status
The C++ I/O system maintains status information about the
outcome of each I/O operation. The current state of the I/O system is held in an object
14
of type iostate, which is an enumeration defined by ios that includes the following
members.
Name Meaning
ios::goodbit No error bits set
ios::eofbit 1 when end-of-file is encountered; 0 otherwise
ios::failbit 1 when a nonfatal I/O error has occurred; 0 otherwise
ios::badbit 1 when a fatal I/O error has occurred; 0 otherwise
STL Container Class Introduction
A Container class is defined as a class that gives you the power to store
any type of data. There are two type of container classes available in STL in C++,
namely “Simple Container Classes” and “Associative Container Classes”. An
Associative Container class associates a key to each object to minimize the average
access time.
Simple Container Classes
vector<>
lists<>
stack<>
queue<>
deque<>
Associative Container Classes
map<>
set<>
multimap<>
multiset<>
Constructor of Vector class
There are 3 overloaded constructors in the vector class excluding the default one.
You can create a vector object with predefined size and values for them.. Suppose you
want to create a vector<int> object whose initial capacity will be 10 and all the values
will be set to 2. Then you can create such an object using one of the overloaded
versions of the vector constructor
vector<int> nums(10,2);
15
If you just want to specify the capacity but don‟t want to assign values for them then
you can use the other constructor which accepts an integer to set the capacity of the
vector like
vector<int> nums(100);
The last constructor allows you to initialize the vector with data from other vectors or
arrays or other collections. Suppose you want to copy one vector to the other then this
constructor proves to be very handy. Here is the code snippet.
vector<int> nums; for(int i=1;i<5;i++) nums.push_back(i); vector<int> codes(nums);
Here codes is a vector. We have copied the contents of nums in codes using the
constructor.
Methods of vector class
Destroy()
Eq()
Lt()
Ucopy()
Ufill()
assign()
at()
begin()
back()
capacity()
clear()
empty()
end()
erase()
front()
get_allocator()
max_size()
insert()
operator=
operator[]
pop_back()
push_back()
rbegin()
rend()
reserve()
resize()
16
size()
swap()
~vector()
assign() and size()
This method is used to assign an initial size to the vector. This method has 2
overloaded versions. Here we have used the first overloaded method. This method
takes an integer argument to initialize the size of the vector.
#include <iostream>
#include <vector>
#include <conio.h>
using namespace std;
int main()
{
vector<char> codes;
codes.assign(10);//Assigning the size to 10.
cout<<codes.size();//prints the size of the vector
getch();
return 0;
}
The next overloaded match takes 2 pointer as arguments. Here is a sample code
#include <iostream>
#include <vector>
#include <conio.h>
using namespace std;
int main()
{
char a[3]={'a','b','c'};
vector<char> orders;
17
orders .assign(a,a+3);
cout<<orders.size();
getch();
return 0;
}
Here the pointer used are nothing but the array name. This concept owes to C.
Basically array name is a pointer to that array.
at()
As vector behaves like an open array, people expect it to show other
behaviors of the array. at() is a method that takes an integer as argument and return
the value at that location. So in a way it simulates the age-old array indexing. Here is
a code snippet.
#include <iostream>
#include <vector>
#include <conio.h>
using namespace std;
int main()
{
vector<int> codes;
for(int i=0;i<10;i++)
codes.push_back(i);
cout<<codes.at(9)<<endl;
getch();
return 0;
}
The output of this code will be 9.
begin() , end()
18
In STL within containers the elements are accessed using iterators.
Iterators are something like pointers. begin() and end() returns the iterator to the
beginning and to the end of the container. Here one thing should be noted end() points
to a location which is one after the physical end of the container. These two methods
are the most used ones in STL, because to traverse a container, you need to create an
iterator. And then to initialize it‟s value to the beginning of the container. Here is the
code to traverse a vector<>. This code make use of begin() and end() methods.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> numbers;
for(int i=0;i<10;i++)
numbers.push_back(i);
//Assiging to the beginning
vector<int>::iterator k = numbers.begin();
//please note that k is kept less than
//numbers.end() because end() points to somewhere which is beyond physical end.
for(;k<numbers.end();k++)
cout<<*k<<endl;
return 0;
}
front(), back()
front() method returns the element at the front of the vector. back() method returns the
element at the back of the vector. Here is the code to understand its operations better.
#include <iostream>
#include <vector>
using namespace std;
19
int main()
{
vector<int> m;
for(int i=0;i<10;i++)
m.push_back(i);
cout<<m.front()<<endl;
cout<<m.back()<<endl;
return 0;
}
The output of this program is
0
9
capacity() , size()
capacity() returns the number of elements the vector can hold initially assigned. For a
vector although it is not very important method. On the other hand the method size()
returns the number of elements currently in the vector. Here is the code that will help
you understand the difference between capacity() and size().
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> m(100);
cout<<m.capacity()<<endl;
for(int i=0;i<10;i++)
m.push_back(i);
cout<<m.size()<<endl;
return 0;
}
20
The output of the program is
100 110
Lists
The list class supports a bidirectional, linear list. Unlike a vector,
which supports random access, a list can be accessed sequentially only. Since lists are
bidirectional, they may be accessed front to back or back to front.
Member Description
reference back( ); Returns a reference to the last element in
const_reference back() const; the list.
iterator begins; Returns an iterator to the first element in
const_iterator begin( ) const; the list.
void clear( ); Removes all elements from the list.
bool empty() const; Returns true if the invoking list is empty
and false otherwise.
iterator ends; Returns an iterator to the end of the list.
const_iterator end( ) const;
iterator erase(iterator i); Removes the element pointed to by i.
Returns an iterator to the element after
the one removed.
iterator erase(iterator start, iterator end); Removes the elements in the range start to
end.
reference front( ); Returns a reference to the first element in
const_reference front( ) const; the list.
Understanding end( )
end( ) does not return a pointer to the last element in a container.
Instead, it returns a pointer one past the last element. Thus, the last element in a
container is pointed to by end( ) - 1. This feature allows us to write very efficient
algorithms that cycle through all of the elements of a container, including the last one,
21
using an iterator. When the iterator has the same value as the one returned by end( ),
we know that all elements have been accessed.
Maps
The map class supports an associative container in which unique keys
are mapped with values. In essence, a key is simply a name that you give to a value.
Once a value has been stored, you can retrieve it by using its key. Thus, in its most
general sense, a map is a list of key/value pairs. The power of a map is that you can
look up a value given its key. For example, you could define a map that uses a
person‟s name as its key and stores that person‟s telephone number as its value.
Associative containers are becoming more popular in programming.
As mentioned, a map can hold only unique keys. Duplicate
keys are not allowed. To create a map that allows nonunique keys, use multimap.
The map container has the following template specification:
template <class Key, class T, class Comp less<Key>,
class Allocator allocator<T>> class map
Here, Key is the data type of the keys, T is the data type of the values being stored
(mapped), and Comp is a function that compares two keys. This defaults to the
standard less( ) utility function object. Allocator is the allocator (which defaults to
allocator)
The following comparison operators are defined for map.
==, <, <=, !=, >, >=
Member Description
iterator begins; Returns an iterator to the first element
const_iterator begin() const; in the map.
void clear( ); Removes all elements from the map.
22
size_type count(const key_type &k) const; Returns the number of times k occurs
in
the map.
bool empty( ) const; Returns true if the invoking map is
empty and false otherwise.
iterator ends; Returns an iterator to the end of
const_iterator end( ) const; the list.
void erase(iterator i); Removes the element pointed to by i.
void erase(iterator start, iterator end); Removes the elements in the range
start to end.
size_type erase(const key_type &k) Removes from the map elements that
have keys with the value k.
iterator find(const key_type &k); Returns an iterator to the specified
iterator insert(iterator i, Inserts val at or after the element
const value_type &val); specified by i. An iterator to the
element is returned.
template <class mIter> Inserts a range of elements.
void insert(Inlter start, mIter end)
pair<iterator, bool> Inserts val into the invoking map. An
insert(const value_type &val); iterator to the element is returned. The
element is inserted only if it does not
already exist. If the element was
inserted, pair<iterator, true> is
returned. Otherwise, pair<iterator,
false> is returned.
Algorithms
Algorithms act on containers. Although each container provides
support for its own basic operations, the standard algorithms provide more extended
or complex actions. They also allow you to work with two different types of
containers at the same time. To have access to the STL algorithms, you must include
<algorithm> in your program.
23
Algorithm Purpose
adjacent_find Searches for adjacent matching elements
within a sequence and returns an iterator to the
. first match.
binary_search Performs a binary search on an ordered
sequence.
y Copies a sequence.
copy_backward Same as copy() except that it moves the
first elements from the end of the sequence
first.
.
count Returns the number of elements in the
sequence.
count_if Returns the number of elements in the
sequence that satisfy some
predicate.
equal Determines if two ranges are the
same.
find_end Searches a range for a subsequence
find_first_of Finds the first element within a
sequence find_if Searches a range for an
element .
includes Determines if one sequence includes all of
the elements in another sequence.
inplace_merge Merges a range with another range.
Removing and Replacing Elements
24
Sometimes it is useful to generate a new sequence that consists of
only certain items from an original sequence. One algorithm that does this is
remove_copy( ). Its general form is shown here:
template <classinmIter, class Outlter, class T>
Outlter remove_copy(Inlter start, inIter end,
Outlter result, const 1 &val);
The remove_copy() algorithm copies elements from the specified range,
removing those that are equal to val. It puts the result into the sequence pointed to by
result and returns an iterator to the end of the result. The output container must be
large enough to hold the result.
To replace one element in a sequence with another when a copy is made, use
replace_copyO. Its general form is shown here:
template <class inIter, class Outlter, class T>
Outlter replace_copy(Inlter start, inIter end,
Outlter result, const T &old, const T &new);
The replace_copy( ) algorithm copies elements from the specified range,
replacing elements equal to old with new. It puts the result into the sequence pointed
to by result and returns an iterator to the end of the result. The output container must
be large enough to hold the result.
Namespaces
The purpose of namespace is to localize the names of identifiers to
avoid name collisions. The C++ programming environment has seen an explosion of
variable, function, and class names. Prior to the invention of namespaces, all of these
names competed for slots in the global namespace and many conflicts arose. For
example, if your program defined a function called abs( ), it could (depending upon its
parameter list) override the standard library function abs() because both names would
be stored in the global namespace.
25
Namespace Fundamentals
The namespace keyword allows you to partition the global namespace
by creating a declarative region. In essence, a namespace defines a scope. Anything
defined within a namespace statement is within the scope of that namespace.
Namespaces allow to group entities like classes, objects and functions under a name.
This way the global scope can be divided in "sub-scopes", each one with its own
name.
The format of namespaces is:
namespace identifier
{
entities
}
Where identifier is any valid identifier and entities is the set of classes, objects and
functions that are included within the namespace. For example:
namespace myNamespace
{
int a, b;
}
In this case, the variables a and b are normal variables declared within a namespace
called myNamespace. In order to access these variables from outside the
myNamespace namespace we have to use the scope operator ::. For example, to
access the previous variables from outside myNamespace we can write:
26
myNamespace::a
myNamespace::b
The functionality of namespaces is especially useful in the case that there is a
possibility that a global object or function uses the same identifier as another one,
causing redefinition errors. For example:
// namespaces
#include <iostream>
using namespace std;
namespace first
{
int var = 5;
}
namespace second
{
double var = 3.1416;
}
int main () {
cout << first::var << endl;
cout << second::var << endl;
return 0;
}
5
3.1416
In this case, there are two global variables with the same name: var. One is defined
within the namespace first and the other one in second. No redefinition errors happen
thanks to namespaces.
using
27
The keyword using is used to introduce a name from a namespace into the current
declarative region. For example:
// using
#include <iostream>
using namespace std;
namespace first
{
int x = 5;
int y = 10;
}
namespace second
{
double x = 3.1416;
double y = 2.7183;
}
int main () {
using first::x;
using second::y;
cout << x << endl;
cout << y << endl;
cout << first::y << endl;
cout << second::x << endl;
return 0;
}
5
2.7183
10
3.1416
Notice how in this code, x (without any name qualifier) refers to first::x whereas y
refers to second::y, exactly as our using declarations have specified. We still have
28
access to first::y and second::x using their fully qualified names.
The keyword using can also be used as a directive to introduce an entire namespace:
// using
#include <iostream>
using namespace std;
namespace first
{
int x = 5;
int y = 10;
}
namespace second
{
double x = 3.1416;
double y = 2.7183;
}
int main () {
using namespace first;
cout << x << endl;
cout << y << endl;
cout << second::x << endl;
cout << second::y << endl;
return 0;
}
5
10
3.1416
2.7183
In this case, since we have declared that we were using namespace first, all direct uses
of x and y without name qualifiers were referring to their declarations in namespace
first.
using and using namespace have validity only in the same block in which they are
stated or in the entire code if they are used directly in the global scope. For example,
29
if we had the intention to first use the objects of one namespace and then those of
another one, we could do something like:
// using namespace example
#include <iostream>
using namespace std;
namespace first
{
int x = 5;
}
namespace second
{
double x = 3.1416;
}
int main () {
{
using namespace first;
cout << x << endl;
}
{
using namespace second;
cout << x << endl;
}
return 0;
}
5
3.1416
.
The STD Namespace
30
Standard C++ defines its entire library in its own namespace
called std.
using narnespace std
This causes the std namespace to be brought into the current
namespace, which gives you direct access to the names of the functions and classes
defined within the library without having to qualify each one with std::.Of course, you
can explicitly qualify each name with std:: if you like. For example, the following
program does not bring the library into the global namespace.
#include <iostream>
int main()
int val;
std: :cout << “Enter a number: “;
std: :cin >> val;
std: :cout << “Ihis is your number:”;
std::cout << std::hex << val;
return 0;
Here, cout, cin, and the manipulator hex are explicitly qualified
by their namespace. That is, to write to standard output, you must specify std::cout; to
read from standard input, you must use std::cin; and the hex manipulator must be
referred to as std::hex.You may not want to bring the standard C++ library into the
global namespace if your program will be making only limited use of it. However, if
your program contains hundreds of references to library names, then including std in
the current namespace is far easier than qualifying each name individually.
The string Class
C++ does not support a built-in string type . It does, however, provide for
two ways of handling strings. Null-terminated character array sometimes referred to
as a C string. The second way is as a class object of type string.
Actually, the string class is a specialization of a more general
template class called basic_string. In fact, there are two specializations of
basic_string: string, which supports 8-bit character strings, and wstring, which
31
supports wide-character strings. Since 8-bit characters are by far the most commonly
used in normal programming, string is the version of basic_string examined here.
. Given that C++ already contains some support for strings as null-
terminated character arrays, it may at first seem that the inclusion of the string class is
an exception to this rule. However, this is actually far from the truth. Here is why:
Null-terminated strings cannot be manipulated by any of the standard C++ operators.
Nor can they take part in normal C++ expressions. For example, consider this
fragment:
char sl [80] s2 [80] s3 [80]
sl = Alpha // can t do
s2 = Beta // can t do
s3 = sl + s2 // error not allowed
As the comments show, in C++ it is not possible to use the assignment operator to
give
a character array a new value (except during initialization), nor is it possible to use the
+ operator to concatenate two strings. These operations must be written using library
functions, as shown here:
strcpy(sl, “Alpha”)
strcpy(s2, “Beta”’)
strcpy(s3, sl)
strcat(s3, s2)
Since null-terminated character arrays are not technically data types in
their own right, the C++ operators cannot be applied to them. This makes even the
most rudimentary string operations clumsy. More than anything else, it is the inability
to operate on null-terminated strings using the standard C++ operators that has driven
the development of a standard string class. Remember, when you define a class in
C++,
you are defining a new data type that may be fully integrated into the C++
environment. This, of course, means that the operators can be overloaded relative to
32
the new class. Therefore, by adding a standard string class, it becomes possible to
manage strings in the same way as any other type of data: through the use of
operators.consider the standard string copy function strcpyO. This function contains
no provision for checking the boundary of the target array. If the source array contains
more characters than the target array can hold, then a program error or system crash is
possible (likely). As you will see, the standard string class prevents such errors.
In the final analysis, there are three reasons for the inclusion of the
standard string class: consistency (a string now defines a data type), convenience (you
may use the standard C++ operators), and safety (array boundaries will not be
overrun). Keep in mind that there is no reason that you should abandon normal, null-
terminated strings altogether. They are still the most efficient way in which to
implement strings. However, when speed is not an overriding concern, using the new
string class gives you access to a safe and fully integrated way to manage strings.
Although not traditionally thought of as part of the STL, string is another
container class defined by C++. To have access to the string class, you must include
<string> in your program.
The string class is very large, with many constructors and member
functions. Also, many member functions have multiple overloaded forms. The string
class supports several constructors. The prototypes for three of its most commonly
used ones are shown here:
string( ); string(const char *str); string(const string &str);
The first form creates an empty string object. The
second creates a string object from the null-terminated string pointed to by str. This
form provides a conversion from null-terminated strings to string objects. The third
form creates a string from another string.
A number of operators that apply to strings are defined for string objects, including:
Operator Meaning
= Assignment
33
+ Concatenation
+= Concatenation assignment
== Equality
!= Inequality
< Less than
<= Less than or equal
> Greater than
>= Greater than or equal
[] Subscripting
<< Output
>> Input
These operators allow the use of string objects in normal
expressions and eliminate the need for calls to functions such as strcpy( ) or strcat( ),
for example. In general, you can mix string objects with normal, null-terminated
strings in expressions. For example, a string object can be assigned a null-terminated
string.
The + operator can be used to concatenate a string object with
another string object or a string object with a C-style string. That is, the following
variations are supported:
string + string
string + C-string
C-string + string
The + operator can also be used to concatenate a character
onto the end of a string.The string class defines the constant npos, which is —1. This
constant represents the length of the longest possible string.
Some string Member Functions
Although most simple string operations can be accomplished using the string
operators, more complex or subtle ones are accomplished using string member
functions.
.Basic String Manipulations
34
To assign one string to another, use the assign() function. Two of its forms are shown
here:
string &assign(const string &strob, size_type start, size_type num); string
&assign(const char *str, size_type num);
In the first form, num characters from strob beginning at the index
specified by start will be assigned to the invoking object. In the second form, the first
num characters of the null-terminated string str are assigned to the invoking object. In
each case, a reference to the invoking object is returned, Of course, it is much easier
to use the = to assign one entire string to another. You will need to use the assign()
function only when assigning a partial string.You can append part of one string to
another using the append() member function. Two of its forms are shown here:
string &append(const string &strob, size_type start, size_type num); string
&append(const char *str, size_type num);
Here, num characters from strob beginning at the index specified by start
will be appended to the invoking object. In the second form, the first num characters
of the null-terminated string str are appended to the invoking object. In each case, a
reference to the invoking object is returned. Of course, it is much easier to use the + to
append one entire string to another. You will need to use the append() function only
when appending a partial string.
You can insert or replace characters within a string using
insert() and replace( ). The prototypes for their most common forms are shown here:
string &insert(size_type start, const string &strob);
string &insert(size_type start, const string &strob,
size_type insStart, size_type nuin);
string &replace(size_type start, size_type num, const string &strob);
The first form of insert( ) inserts strob into the invoking string at
the index specified by start. The second form of insert( ) function inserts num
characters from strob beginning at intStart into the invoking string at the index
specified by start.
35
Beginning at start,replace( ) replaces num characters from the invoking string, with
strob.
You can remove characters from a string using erase( ).
Searching a String
The string class provides several member functions that search a
string, including find() and rfind( ). Here are the prototypes for the most common
versions of these functions:
size_type find(const string &strob, size_type start=O) const;
size_type rfind(const string &strob, size_type start=npos) const;
Beginning at start, find( ) searches the invoking string for the
first occurrence of the string contained in strob. If found, find( ) returns the index at
which the match occurs within the invoking string. If no match is found, then npos is
returned. rfind() is the opposite of find( ). Beginning at start, it searches the invoking
string in the reverse direction for the first occurrence of the string contained in strob
(i.e. it finds the last occurrence of strob within the invoking string). If found, rfind( )
returns the index at which the match occurs within the invoking string. If no match is
found, npos is returned.
Comparing Strings
To compare the entire contents of one string object to another, you will normally use
the overloaded relational operators described earlier. However, if you want to
compare a portion of one string to another, you will need to use the compare()
member function, shown here:
int compare(size_type start, size_type num, const string &strob) const;
Here, num characters in strob, beginning at start, will be compared
against the invoking string. If the invoking string is less than strob, compare( ) will
return less than zero. If the invoking string is greater than strob, it will return greater
than zero. If strob is equal to the invoking string, compare( ) will return zero.
QUESTIONS
PART –A (2-MARKS)
36
1. What is Generic programming?
2. What is Function Template?
3. What is Class Template?
4. What are Streams?
5. What are C++ streams?
6. Define Predefined console stream
7. Define Unformatted I/o operations
8. Define formatted console operations
9. What are Manipulators?
10. What are the types of
Manipulators?
11. Define custom / user defined
manipulators
12.What is a File?
13. Explain the various file stream
classes needed for File Manipulators.
14. What are the steps involving
Opening and Closing of Files.
15.Define the term Standard Template
Library (STL).
PART –B(16 MARKS)
1. What is generic programming? What are its advantages and state some of its
Applications?
2. What is Function template? Write a suitable example program.
3. Explain overloaded function templates. With suitable example program.
4. What is a class template? Explain the syntax of a class template with suitable
program.
5. Draw console stream class hierarchy and explain its members.
7. Explain the various methods of performing formatted stream I/O operations.
7. What are manipulators? List the various predefined manipulators supported by c++
I/O streams.
8. Explain how standard manipulators are implemented.
9. What is a File? What are steps involved in manipulating a file in a C++ programs?
10. What are file modes? Describe various file mode options available
12. What are file pointers? Describe get-pointers and put-pointers?
13.Expalin in detail about STL.