<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" version="2.0">

<channel>
	<title>Learn C++</title>
	
	<link>http://www.learncpp.com</link>
	<description />
	<lastBuildDate>Sun, 28 Feb 2010 19:38:21 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/LearnCpp" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="learncpp" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>17.4 — std::string character access and conversion to C-style arrays</title>
		<link>http://www.learncpp.com/cpp-tutorial/17-4-stdstring-character-access-and-conversion-to-c-style-arrays/</link>
		<comments>http://www.learncpp.com/cpp-tutorial/17-4-stdstring-character-access-and-conversion-to-c-style-arrays/#comments</comments>
		<pubDate>Sun, 04 Oct 2009 17:54:58 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[C++ Tutorial]]></category>

		<guid isPermaLink="false">http://www.learncpp.com/?p=432</guid>
		<description><![CDATA[Character access
There are two almost identical ways to access characters in a string.  The easier to use and faster version is the overloaded operator[]:



char&#038; string::operator[] (size_type nIndex)
const char&#038; string::operator[] (size_type nIndex) const

Both of these functions return the character with index nIndex
Passing an invalid index results in undefined behavior
Using length() as the index is valid [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Character access</strong></p>
<p>There are two almost identical ways to access characters in a string.  The easier to use and faster version is the overloaded operator[]:</p>
<table border=1 cellspacing=0 cellpadding=3 width=100%>
<tr>
<td>
<b>char&#038; string::operator[] (size_type nIndex)</b><br />
<b>const char&#038; string::operator[] (size_type nIndex) const</b></p>
<ul>
<li>Both of these functions return the character with index nIndex
<li>Passing an invalid index results in undefined behavior
<li>Using length() as the index is valid for const strings only, and returns the value generated by the string&#8217;s default constructor.  It is not recommended that you do this.
<li>Because char&#038; is the return type, you can use this to edit characters in the array
</ul>
<p>Sample code:</p>
<pre class="brush: cpp;">
string sSource(&quot;abcdefg&quot;);
cout &lt;&lt; sSource[5] &lt;&lt; endl;
sSource[5] = 'X';
cout &lt;&lt; sSource &lt;&lt; endl;
</pre>
<p>Output:</p>
<pre>
f
abcdeXg
</pre>
</td>
</tr>
</table>
<p></p>
<p>There is also a non-operator version.  This version is slower since it uses exceptions to check if the nIndex is valid.  If you are not sure whether nIndex is valid, you should use this version to access the array:</p>
<table border=1 cellspacing=0 cellpadding=3 width=100%>
<tr>
<td>
<b>char&#038; string::at (size_type nIndex)</b><br />
<b>const char&#038; string::at (size_type nIndex) const</b></p>
<ul>
<li>Both of these functions return the character with index nIndex
<li>Passing an invalid index results in an out_of_range exception
<li>Because char&#038; is the return type, you can use this to edit characters in the array
</ul>
<p>Sample code:</p>
<pre class="brush: cpp;">
string sSource(&quot;abcdefg&quot;);
cout &lt;&lt; sSource.at(5) &lt;&lt; endl;
sSource.at(5) = 'X';
cout &lt;&lt; sSource &lt;&lt; endl;
</pre>
<p>Output:</p>
<pre>
f
abcdeXg
</pre>
</td>
</tr>
</table>
<p></p>
<p><strong>Conversion to C-style arrays</strong></p>
<p>Many functions (including all C functions) expect strings to be formatted as C-style strings rather than std::string.  For this reason, std::string provides 3 different ways to convert std::string to C-style strings.</p>
<table border=1 cellspacing=0 cellpadding=3 width=100%>
<tr>
<td>
<b>const char* string::c_str () const</b></p>
<ul>
<li>Returns the contents of the string as a const C-style string
<li>A null terminator is appended
<li>The C-style string is owned by the std::string and should not be deleted
</ul>
<p>Sample code:</p>
<pre class="brush: cpp;">
string sSource(&quot;abcdefg&quot;);
cout &lt;&lt; strlen(sSource.c_str());
</pre>
<p>Output:</p>
<pre>
7
</pre>
</td>
</tr>
</table>
<p></p>
<table border=1 cellspacing=0 cellpadding=3 width=100%>
<tr>
<td>
<b>const char* string::data () const</b></p>
<ul>
<li>Returns the contents of the string as a const C-style string
<li>A null terminator is <b>not</b> appended
<li>The C-style string is owned by the std::string and should not be deleted
</ul>
<p>Sample code:</p>
<pre class="brush: cpp;">
string sSource(&quot;abcdefg&quot;);
char *szString = &quot;abcdefg&quot;;
// memcmp compares the first n characters of two C-style strings and returns 0 if they are equal
if (memcmp(sSource.data(), szString, sSource.length()) == 0)
    cout &lt;&lt; &quot;The strings are equal&quot;;
else
    cout &lt;&lt; &quot;The strings are not equal&quot;;
</pre>
<p>Output:</p>
<pre>
The strings are equal
</pre>
</td>
</tr>
</table>
<p></p>
<table border=1 cellspacing=0 cellpadding=3 width=100%>
<tr>
<td>
<b>size_type string::copy(char *szBuf, size_type nLength) const</b><br />
<b>size_type string::copy(char *szBuf, size_type nLength, size_type nIndex) const</b></p>
<ul>
<li>Both flavors copy at most nLength characters of the string to szBuf, beginning with character nIndex
<li>The number of characters copied is returned
<li>No null is appended.  It is up to the caller to ensure szBuf is initialized to NULL or terminate the string using the returned length
<li>The caller is responsible for not overflowing szBuf
</ul>
<p>Sample code:</p>
<pre class="brush: cpp;">
string sSource(&quot;sphinx of black quartz, judge my vow&quot;);

char szBuf[20];
int nLength = sSource.copy(szBuf, 5, 10);
szBuf[nLength]='\0';  // Make sure we terminate the string in the buffer

cout &lt;&lt; szBuf &lt;&lt; endl;
</pre>
<p>Output:</p>
<pre>
black
</pre>
</td>
</tr>
</table>
<p></p>
<p>Unless you need every bit of efficiency, c_str() is the easiest and safest of the three functions to use.</p>
<table border=0 cellpadding=3>
<tr>
<td>
        <a href="" style="text-decoration:none"><img src="http://www.learncpp.com/images/CppTutorial/next.png" align=middle></a>
</td>
</tr>
<tr>
<td>
        <a href="http://www.learncpp.com/#Chapter17" style="text-decoration:none"><img src="http://www.learncpp.com/images/CppTutorial/up.png" align=middle> Index</a>
</td>
</tr>
<tr>
<td>
        <a href="http://www.learncpp.com/cpp-tutorial/17-3-stdstring-length-and-capacity/" style="text-decoration:none"><img src="http://www.learncpp.com/images/CppTutorial/prev.png" align=middle> 17.3 &#8212; std::string length and capacity</a>
</td>
</tr>
</table>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/LearnCpp?a=LWZhHLSIuNc:T5J_Cy_sneY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/LearnCpp?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/LearnCpp?a=LWZhHLSIuNc:T5J_Cy_sneY:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/LearnCpp?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/LearnCpp?a=LWZhHLSIuNc:T5J_Cy_sneY:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/LearnCpp?i=LWZhHLSIuNc:T5J_Cy_sneY:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/LearnCpp?a=LWZhHLSIuNc:T5J_Cy_sneY:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/LearnCpp?i=LWZhHLSIuNc:T5J_Cy_sneY:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.learncpp.com/cpp-tutorial/17-4-stdstring-character-access-and-conversion-to-c-style-arrays/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>17.3 — std::string length and capacity</title>
		<link>http://www.learncpp.com/cpp-tutorial/17-3-stdstring-length-and-capacity/</link>
		<comments>http://www.learncpp.com/cpp-tutorial/17-3-stdstring-length-and-capacity/#comments</comments>
		<pubDate>Sun, 27 Sep 2009 18:09:32 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[C++ Tutorial]]></category>

		<guid isPermaLink="false">http://www.learncpp.com/?p=400</guid>
		<description><![CDATA[Once you&#8217;ve created strings, it&#8217;s often useful to know how long they are.  This is where length and capacity operations come into play.  We&#8217;ll also discuss various ways to convert std::string back into C-style strings, so you can use them with functions that expect strings of type char*.
Length of a string
The length of [...]]]></description>
			<content:encoded><![CDATA[<p>Once you&#8217;ve created strings, it&#8217;s often useful to know how long they are.  This is where length and capacity operations come into play.  We&#8217;ll also discuss various ways to convert std::string back into C-style strings, so you can use them with functions that expect strings of type char*.</p>
<p><strong>Length of a string</strong></p>
<p>The length of the string is quite simple &#8212; it&#8217;s the number of characters in the string.  There are two identical functions for determining string length:</p>
<table border=1 cellspacing=0 cellpadding=3 width=100%>
<tr>
<td>
<b>size_type string::length() const</b><br />
<b>size_type string::size() const</b></p>
<ul>
<li>Both of these functions return the current number of characters in the string, excluding the null terminator.
</ul>
<p>Sample code:</p>
<pre class="brush: cpp;">
string sSource(&quot;012345678&quot;);
cout &lt;&lt; sSource.length() &lt;&lt; endl;
</pre>
<p>Output:</p>
<pre>
9
</pre>
</td>
</tr>
</table>
<p></p>
<p>Although it&#8217;s possible to use length() to determine whether a string has any characters or not, it&#8217;s more efficient to use the empty() function:</p>
<table border=1 cellspacing=0 cellpadding=3 width=100%>
<tr>
<td>
<b>bool string::empty() const</b></p>
<ul>
<li>Returns true if the string has no characters, false otherwise.
</ul>
<p>Sample code:</p>
<pre class="brush: cpp;">
string sString1(&quot;Not Empty&quot;);
cout &lt;&lt; (sString1.empty() ? &quot;true&quot; : &quot;false&quot;) &lt;&lt; endl;
string sString2; // empty
cout &lt;&lt; (sString2.empty() ? &quot;true&quot; : &quot;false&quot;)  &lt;&lt; endl;
</pre>
<p>Output:</p>
<pre>
false
true
</pre>
</td>
</tr>
</table>
<p></p>
<p>There is one more size-related function that you will probably never use, but we&#8217;ll include it here for completeness:</p>
<table border=1 cellspacing=0 cellpadding=3 width=100%>
<tr>
<td>
<b>size_type string::max_size() const</b></p>
<ul>
<li>Returns the maximum number of characters that a string is allowed to have.
<li>This value will vary depending on operating system and system architecture.
</ul>
<p>Sample code:</p>
<pre class="brush: cpp;">
string sString(&quot;MyString&quot;);
cout &lt;&lt; sString.max_size() &lt;&lt; endl;
</pre>
<p>Output:</p>
<pre>
4294967294
</pre>
</td>
</tr>
</table>
<p></p>
<p><strong>Capacity of a string</strong></p>
<p>The capacity of a string reflects how much memory the string allocated to hold it&#8217;s contents.  This value is measured in string characters, excluding the NULL terminator.  For example, a string with capacity 8 could hold 8 characters.</p>
<table border=1 cellspacing=0 cellpadding=3 width=100%>
<tr>
<td>
<b>size_type string::capacity() const</b></p>
<ul>
<li>Returns the number of characters a string can hold without reallocation.
</ul>
<p>Sample code:</p>
<pre class="brush: cpp;">
string sString(&quot;01234567&quot;);
cout &lt;&lt; &quot;Length: &quot; &lt;&lt; sString.length() &lt;&lt; endl;
cout &lt;&lt; &quot;Capacity: &quot; &lt;&lt; sString.capacity() &lt;&lt; endl;
</pre>
<p>Output:</p>
<pre>
Length: 8
Capacity: 15
</pre>
</td>
</tr>
</table>
<p></p>
<p>Note that the capacity is higher than the length of the string!  Although our string was length 8, the string actually allocated enough memory for 15 characters!  Why was this done?</p>
<p>The important thing to recognize here is that if a user wants to put more characters into a string than the string has capacity for, the string has to be reallocated to a larger capacity.  For example, if a string had both length and capacity of 8, then adding any characters to the string would force a reallocation.  By making the capacity larger than the actual string, this gives the user some buffer room to expand the string before reallocation needs to be done.</p>
<p>As it turns out, reallocation is bad for several reasons:</p>
<p>First, reallocating a string is comparatively expensive.  First, new memory has to be allocated.  Then each character in the string has to be copied to the new memory.  This can take a long time if the string is big.  Finally, the old memory has to be deallocated.  If you are doing many reallocations, this process can slow your program down significantly.</p>
<p>Second, whenever a string is reallocated, the contents of the string change to a new memory address.  This means all references, pointers, and iterators to the string become invalid!</p>
<p>Note that it&#8217;s not always the case that strings will be allocated with capacity greater than length.  Consider the following program:</p>
<pre class="brush: cpp;">
string sString(&quot;0123456789abcde&quot;);
cout &lt;&lt; &quot;Length: &quot; &lt;&lt; sString.length() &lt;&lt; endl;
cout &lt;&lt; &quot;Capacity: &quot; &lt;&lt; sString.capacity() &lt;&lt; endl;
</pre>
<p>This program outputs:</p>
<pre>
Length: 15
Capacity: 15
</pre>
<p>(Results may vary depending on compiler).</p>
<p>Let&#8217;s add one character to the string and watch the capacity change:</p>
<pre class="brush: cpp;">
string sString(&quot;0123456789abcde&quot;);
cout &lt;&lt; &quot;Length: &quot; &lt;&lt; sString.length() &lt;&lt; endl;
cout &lt;&lt; &quot;Capacity: &quot; &lt;&lt; sString.capacity() &lt;&lt; endl;

// Now add a new character
sString += &quot;f&quot;;
cout &lt;&lt; &quot;Length: &quot; &lt;&lt; sString.length() &lt;&lt; endl;
cout &lt;&lt; &quot;Capacity: &quot; &lt;&lt; sString.capacity() &lt;&lt; endl;
</pre>
<p>This produces the result:</p>
<pre>
Length: 15
Capacity: 15
Length: 16
Capacity: 31
</pre>
<table border=1 cellspacing=0 cellpadding=3 width=100%>
<tr>
<td>
<b>void string::reserve() </b><br />
<b>void string::reserve(size_type unSize) </b></p>
<ul>
<li>The second flavor of this function sets the capacity of the string to at least unSize (it can be greater).  Note that this may require a reallocation to occur.
<li>If the first flavor of the function is called, or the second flavor is called with unSize less than the current capacity, the function will try to shrink the capacity to match the length.  This is a non-binding request.
</ul>
<p>Sample code:</p>
<pre class="brush: cpp;">
string sString(&quot;01234567&quot;);
cout &lt;&lt; &quot;Length: &quot; &lt;&lt; sString.length() &lt;&lt; endl;
cout &lt;&lt; &quot;Capacity: &quot; &lt;&lt; sString.capacity() &lt;&lt; endl;

sString.reserve(200);
cout &lt;&lt; &quot;Length: &quot; &lt;&lt; sString.length() &lt;&lt; endl;
cout &lt;&lt; &quot;Capacity: &quot; &lt;&lt; sString.capacity() &lt;&lt; endl;

sString.reserve();
cout &lt;&lt; &quot;Length: &quot; &lt;&lt; sString.length() &lt;&lt; endl;
cout &lt;&lt; &quot;Capacity: &quot; &lt;&lt; sString.capacity() &lt;&lt; endl;
</pre>
<p>Output:</p>
<pre>
Length: 8
Capacity: 15
Length: 8
Capacity: 207
Length: 8
Capacity: 207
</pre>
</td>
</tr>
</table>
<p></p>
<p>This example shows two interesting things.  First, although we requested a capacity of 200, we actually got a capacity of 207.  The capacity is always guaranteed to be at least as large as your request, but may be larger.  We then requested the capacity change to fit the string.  This request was ignored, as the capacity did not change.</p>
<p>If you know in advance that you&#8217;re going to be constructing a large string by doing lots of string operations that will add to the size of the string, you can avoid having the string reallocated multiple times by immediately setting the string to it&#8217;s final capacity:</p>
<pre class="brush: cpp;">
#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;cstdlib&gt; // for rand() and srand()
#include &lt;ctime&gt; // for time()

using namespace std;

int main()
{
    srand(time(0)); // seed random number generator

    string sString; // length 0
    sString.reserve(64); // reserve 64 characters

    // Fill string up with random lower case characters
    for (int nCount=0; nCount &lt; 64; ++nCount)
        sString += 'a' + rand() % 26;

    cout &lt;&lt; sString;
}
</pre>
<p>The result of this program will change each time, but here&#8217;s the output from one execution:</p>
<pre>
wzpzujwuaokbakgijqdawvzjqlgcipiiuuxhyfkdppxpyycvytvyxwqsbtielxpy
</pre>
<p>Rather than having to reallocate sString multiple times, we set the capacity once and then fill the string up.  This can make a huge difference in performance when constructing large strings via concatenation.</p>
<table border=0 cellpadding=3>
<tr>
<td>
        <a href="http://www.learncpp.com/cpp-tutorial/17-4-stdstring-character-access-and-conversion-to-c-style-arrays/" style="text-decoration:none"><img src="http://www.learncpp.com/images/CppTutorial/next.png" align=middle> 17.4 &#8212; std::string character access and conversion to C-style arrays</a>
</td>
</tr>
<tr>
<td>
        <a href="http://www.learncpp.com/#Chapter17" style="text-decoration:none"><img src="http://www.learncpp.com/images/CppTutorial/up.png" align=middle> Index</a>
</td>
</tr>
<tr>
<td>
        <a href="http://www.learncpp.com/cpp-tutorial/17-2-stdstring-construction-and-destruction/" style="text-decoration:none"><img src="http://www.learncpp.com/images/CppTutorial/prev.png" align=middle> 17.2 &#8212; std::string construction and destruction</a>
</td>
</tr>
</table>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/LearnCpp?a=f7kQ90U_JK4:E1OmccgJH7A:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/LearnCpp?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/LearnCpp?a=f7kQ90U_JK4:E1OmccgJH7A:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/LearnCpp?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/LearnCpp?a=f7kQ90U_JK4:E1OmccgJH7A:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/LearnCpp?i=f7kQ90U_JK4:E1OmccgJH7A:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/LearnCpp?a=f7kQ90U_JK4:E1OmccgJH7A:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/LearnCpp?i=f7kQ90U_JK4:E1OmccgJH7A:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.learncpp.com/cpp-tutorial/17-3-stdstring-length-and-capacity/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>17.2 — std::string construction and destruction</title>
		<link>http://www.learncpp.com/cpp-tutorial/17-2-ststring-construction-and-destruction/</link>
		<comments>http://www.learncpp.com/cpp-tutorial/17-2-ststring-construction-and-destruction/#comments</comments>
		<pubDate>Sun, 20 Sep 2009 18:10:33 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[C++ Tutorial]]></category>

		<guid isPermaLink="false">http://www.learncpp.com/?p=348</guid>
		<description><![CDATA[In this lesson, we&#8217;ll take a look at how to construct objects of std::string, as well as how to create strings from numbers and vice-versa.
String construction
The string classes have a number of constructors that can be used to create strings.  We&#8217;ll take a look at each of them here.
Note: string::size_type resolves to size_t, which [...]]]></description>
			<content:encoded><![CDATA[<p>In this lesson, we&#8217;ll take a look at how to construct objects of std::string, as well as how to create strings from numbers and vice-versa.</p>
<p><strong>String construction</strong></p>
<p>The string classes have a number of constructors that can be used to create strings.  We&#8217;ll take a look at each of them here.</p>
<p>Note: string::size_type resolves to size_t, which is the same unsigned integral type that is returned by the sizeof operator.  It&#8217;s actual size varies depending on environment.  For purposes of this tutorial, envision it as an unsigned int.</p>
<table border=1 cellspacing=0 cellpadding=3 width=100%>
<tr>
<td>
<b>string::string()</b></p>
<ul>
<li>This is the default constructor.  It creates an empty string.
</ul>
<p>Sample code:</p>
<pre class="brush: cpp;">
std::string sSource;
cout &lt;&lt; sSource;
</pre>
<p>Output:</p>
<pre>
</pre>
</td>
</tr>
</table>
<p></p>
<table border=1 cellspacing=0 cellpadding=3 width=100%>
<tr>
<td>
<b>string::string(const string&#038; strString)</b></p>
<ul>
<li>This is the copy constructor.  This constructor creates a new string as a copy of strString.
</ul>
<p>Sample code:</p>
<pre class="brush: cpp;">
string sSource(&quot;my string&quot;);
string sOutput(sSource);
cout &lt;&lt; sOutput;
</pre>
<p>Output:</p>
<pre>
my string
</pre>
</td>
</tr>
</table>
<p></p>
<table border=1 cellspacing=0 cellpadding=3 width=100%>
<tr>
<td>
<b>string::string(const string&#038; strString, size_type unIndex)</b><br />
<b>string::string(const string&#038; strString, size_type unIndex, size_type unLength)</b></p>
<ul>
<li>This constructor creates a new string that contains at most unLength characters from strString, starting with index unIndex.  If a NULL is encountered, the string copy will end, even if unLength has not been reached.
<li> If no unLength is supplied, all characters starting from unIndex will be used.
<li>If unIndex is larger than the size of the string, the out_of_range exception will be thrown.
</ul>
<p>Sample code:</p>
<pre class="brush: cpp;">
string sSource(&quot;my string&quot;);
string sOutput(sSource, 3);
cout &lt;&lt; sOutput&lt;&lt; endl;
string sOutput2(sSource, 3, 4);
cout &lt;&lt; sOutput2 &lt;&lt; endl;
</pre>
<p>Output:</p>
<pre>
string
stri
</pre>
</td>
</tr>
</table>
<p></p>
<table border=1 cellspacing=0 cellpadding=3 width=100%>
<tr>
<td>
<b>string::string(const char *szCString)</b></p>
<ul>
<li>This constructor creates a new string from the C-style string szCString, up to but not including the NULL terminator.
<li>If the resulting size exceeds the maximum string length, the length_error exception will be thrown.
<li><b>Warning:</b> szCString must not be NULL.
</ul>
<p>Sample code:</p>
<pre class="brush: cpp;">
const char *szSource(&quot;my string&quot;);
string sOutput(szSource);
cout &lt;&lt; sOutput &lt;&lt; endl;
</pre>
<p>Output:</p>
<pre>
my string
</pre>
</td>
</tr>
</table>
<p></p>
<table border=1 cellspacing=0 cellpadding=3 width=100%>
<tr>
<td>
<b>string::string(const char *szCString, size_type unLength)</b></p>
<ul>
<li>This constructor creates a new string from the first unLength chars from the C-style string szCString.
<li>If the resulting size exceeds the maximum string length, the length_error exception will be thrown.
<li><b>Warning:</b> For this function only, NULLs are not treated as end-of-string characters in szCString!  This means it is possible to read off the end of your string if unLength is too big.  Be careful not to overflow your string buffer!
</ul>
<p>Sample code:</p>
<pre class="brush: cpp;">
const char *szSource(&quot;my string&quot;);
string sOutput(szSource, 4);
cout &lt;&lt; sOutput &lt;&lt; endl;
</pre>
<p>Output:</p>
<pre>
my s
</pre>
</td>
</tr>
</table>
<p></p>
<table border=1 cellspacing=0 cellpadding=3 width=100%>
<tr>
<td>
<b>string::string(size_type nNum, char chChar)</b></p>
<ul>
<li>This constructor creates a new string initialized by nNum occurances of the character chChar.
<li>If the resulting size exceeds the maximum string length, the length_error exception will be thrown.
</ul>
<p>Sample code:</p>
<pre class="brush: cpp;">
string sOutput(4, 'Q');
cout &lt;&lt; sOutput &lt;&lt; endl;
</pre>
<p>Output:</p>
<pre>
QQQQ
</pre>
</td>
</tr>
</table>
<p></p>
<table border=1 cellspacing=0 cellpadding=3 width=100%>
<tr>
<td>
<b>template&lt;class InputIterator&gt; string::string(InputIterator itBeg, InputIterator itEnd)</b></p>
<ul>
<li>This constructor creates a new string initialized by the characters of range [itBeg, itEnd).
<li>If the resulting size exceeds the maximum string length, the length_error exception will be thrown.
</ul>
<p>No sample code for this one.  It&#8217;s obscure enough you&#8217;ll probably never use it.
</td>
</tr>
</table>
<p></p>
<table border=1 cellspacing=0 cellpadding=3 width=100%>
<tr>
<td>
<b>string::~string()</b></p>
<p><strong>String construction</strong></p>
<ul>
<li>This is the destructor.  It destroys the string and frees the memory.
</ul>
<p>No sample code here either since the destructor isn&#8217;t called explicitly.
</td>
</tr>
</table>
<p></p>
<p><strong>Constructing strings from numbers</strong></p>
<p>One notable omission in the std::string class is the lack of ability to create strings from numbers.  For example:</p>
<pre class="brush: cpp;">
    string sFour(4);
</pre>
<p>Produces the following error:</p>
<pre>
c:\vcprojects\test2\test2\test.cpp(10) : error C2664: &#039;std::basic_string&lt;_Elem,_Traits,_Ax&gt;::basic_string(std::basic_string&lt;_Elem,_Traits,_Ax&gt;::_Has_debug_it)&#039; : cannot convert parameter 1 from &#039;int&#039; to &#039;std::basic_string&lt;_Elem,_Traits,_Ax&gt;::_Has_debug_it&#039;
</pre>
<p>Remember what I said about the string classes producing horrible looking errors?  The relevant bit of information here is:</p>
<pre>cannot convert parameter 1 from &#039;int&#039; to &#039;std::basic_string</pre>
<p>In other words, it tried to convert your int into a string but failed.</p>
<p>The easiest way to convert numbers into strings is to involve the std::ostringstream class.  std::ostringstream is already set up to accept input from a variety of sources, including characters, numbers, strings, etc&#8230;  It is also capable of outputting strings (either via the extraction operator>>, or via the str() function).  For more information on std::ostringstream, see <a href="http://www.learncpp.com/cpp-tutorial/134-stream-classes-for-strings/">Lesson 13.4 &#8212; Stream classes for strings</a>.  </p>
<p>Here&#8217;s a simple solution for creating std::string from various types of inputs:</p>
<pre class="brush: cpp;">
#include &lt;iostream&gt;
#include &lt;sstream&gt;
#include &lt;string&gt;

template &lt;typename T&gt;
inline std::string ToString(T tX)
{
    std::ostringstream oStream;
    oStream &lt;&lt; tX;
    return oStream.str();
}
</pre>
<p>Here&#8217;s some sample code to test it:</p>
<pre class="brush: cpp;">
int main()
{
    string sFour(ToString(7));
    string sSixPointSeven(ToString(6.7));
    string sA(ToString('A'));
    cout &lt;&lt; sFour &lt;&lt; endl;
    cout &lt;&lt; sSixPointSeven &lt;&lt; endl;
    cout &lt;&lt; sA &lt;&lt; endl;
}
</pre>
<p>And the output:</p>
<pre>
4
6.7
A
</pre>
<p>Note that this solution omits any error checking.  It is possible that inserting tX into oStream could fail.  An appropriate response would be to throw an exception if the conversation fails.</p>
<p><strong>Converting strings to numbers</strong></p>
<p>Similar to the solution above:</p>
<pre class="brush: cpp;">
#include &lt;iostream&gt;
#include &lt;sstream&gt;
#include &lt;string&gt;

template &lt;typename T&gt;
inline bool FromString(const std::string&amp; sString, T &amp;tX)
{
    std::istringstream iStream(sString);
    return (iStream &gt;&gt; tX) ? true : false;
}
</pre>
<p>Here&#8217;s some sample code to test it:</p>
<pre class="brush: cpp;">
int main()
{
    double dX;
    if (FromString(&quot;3.4&quot;, dX))
        cout &lt;&lt; dX &lt;&lt; endl;
    if (FromString(&quot;ABC&quot;, dX))
        cout &lt;&lt; dX &lt;&lt; endl;
}
</pre>
<p>And the output:</p>
<pre>
3.4
</pre>
<p>Note that the second conversation failed and returned false.</p>
<table border=0 cellpadding=3>
<tr>
<td>
        <a href="http://www.learncpp.com/cpp-tutorial/17-3-stdstring-length-and-capacity/" style="text-decoration:none"><img src="http://www.learncpp.com/images/CppTutorial/next.png" align=middle> 17.3 &#8212; std::string length and capacity</a>
</td>
</tr>
<tr>
<td>
        <a href="http://www.learncpp.com/#Chapter17" style="text-decoration:none"><img src="http://www.learncpp.com/images/CppTutorial/up.png" align=middle> Index</a>
</td>
</tr>
<tr>
<td>
        <a href="http://www.learncpp.com/cpp-tutorial/17-1-stdstring-and-stdwstring/" style="text-decoration:none"><img src="http://www.learncpp.com/images/CppTutorial/prev.png" align=middle> 17.1 &#8212; std::string and std::wstring</a>
</td>
</tr>
</table>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/LearnCpp?a=Gq5gSKWRdLQ:C6dwDdqDXXs:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/LearnCpp?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/LearnCpp?a=Gq5gSKWRdLQ:C6dwDdqDXXs:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/LearnCpp?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/LearnCpp?a=Gq5gSKWRdLQ:C6dwDdqDXXs:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/LearnCpp?i=Gq5gSKWRdLQ:C6dwDdqDXXs:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/LearnCpp?a=Gq5gSKWRdLQ:C6dwDdqDXXs:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/LearnCpp?i=Gq5gSKWRdLQ:C6dwDdqDXXs:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.learncpp.com/cpp-tutorial/17-2-ststring-construction-and-destruction/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>17.1 — std::string and std::wstring</title>
		<link>http://www.learncpp.com/cpp-tutorial/17-1-stdstring-and-stdwstring/</link>
		<comments>http://www.learncpp.com/cpp-tutorial/17-1-stdstring-and-stdwstring/#comments</comments>
		<pubDate>Sat, 12 Sep 2009 22:43:33 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[C++ Tutorial]]></category>

		<guid isPermaLink="false">http://www.learncpp.com/?p=329</guid>
		<description><![CDATA[The standard library contains many useful classes &#8212; but perhaps the most useful is std::string.  std::string (and std::wstring) is a string class that provides many operations to assign, compare, and modify strings.  In this chapter, we&#8217;ll look into these string classes in depth.
Note: C-style strings will be referred to as &#8220;C-style strings&#8221;, whereas [...]]]></description>
			<content:encoded><![CDATA[<p>The standard library contains many useful classes &#8212; but perhaps the most useful is std::string.  std::string (and std::wstring) is a string class that provides many operations to assign, compare, and modify strings.  In this chapter, we&#8217;ll look into these string classes in depth.</p>
<p>Note: C-style strings will be referred to as &#8220;C-style strings&#8221;, whereas std::strings (and std::wstring) will be referred to simply as &#8220;strings&#8221;.</p>
<p><strong>Motivation for a string class</strong></p>
<p>In a previous lesson, we covered  <a href="http://www.learncpp.com/cpp-tutorial/66-c-style-strings/">C-style strings</a>, which using char arrays to store a string of characters.  If you&#8217;ve tried to do anything with C-style strings, you&#8217;ll very quickly come to the conclusion that they are a pain to work with, easy to mess up, and hard to debug.</p>
<p>C-style strings have many shortcomings, primarily revolving around the fact that you have to do all the memory management yourself.  For example, if you want to assign the string &#8220;hello!&#8221; into a buffer, you have to first dynamically allocate a buffer of the correct length:</p>
<pre class="brush: cpp;">
char *strHello = new char(7);
</pre>
<p>Don&#8217;t forget to account for an extra character for the null terminator!</p>
<p>Then you have to actually copy the value in:</p>
<pre class="brush: cpp;">
strcpy(strHello, &quot;hello!&quot;);
</pre>
<p>Hopefully you made your buffer large enough so there&#8217;s no buffer overflow!</p>
<p>And of course, because the string is dynamically allocated, you have to remember to deallocate it properly when you&#8217;re done with it:</p>
<pre class="brush: cpp;">
delete[] strHello;
</pre>
<p>Don&#8217;t forget to use array delete instead of normal delete!</p>
<p>Furthermore, many of the intuitive operators that C provides to work with numbers, such as assignment and comparisons, simply don&#8217;t work with C-style strings.  Sometimes these will appear to work but actually produce incorrect results &#8212; for example, comparing two C-style strings using == will actually do a pointer comparison, not a string comparison.  Assigning one C-style string to another using operator= will appear to work at first, but is actually doing a pointer copy (shallow copy), which is not generally what you want.  These kinds of things can lead to program crashes that are very hard to find and debug!</p>
<p>The bottom line is that working with C-style strings requires remembering a lot of nit-picky rules about what is safe/unsafe, memorizing a bunch of functions that have funny names like strcat() and strcmp() instead of using intuitive operators, and doing lots of manual memory management.</p>
<p>Fortunately, C++ and the standard library provide a much better way to deal with strings: the std::string and std::wstring classes.  By making use of C++ concepts such as constructors, destructors, and operator overloading, std::string allows you to create and manipulate strings in an intuitive and safe manner!  No more memory management, no more weird function names, and a much reduced potential for disaster.</p>
<p>Sign me up!</p>
<p><strong>String overview</strong></p>
<p>All string functionality in the standard library lives in the &lt;string&gt; header file.  To use it, simply include the string header:</p>
<pre class="brush: cpp;">
    #include &lt;string&gt;
</pre>
<p>There are actually 3 different string classes in the string header.  The first is a templated base class named basic_string<>:</p>
<pre class="brush: cpp;">
namespace std
{
    template&lt;class charT, class traits = char_traits&lt;charT&gt;, class Allocator = allocator&lt;charT&gt; &gt;
        class basic_string;
}
</pre>
<p>You won&#8217;t be working with this class directly, so don&#8217;t worry about what traits or an Allocator is for the time being.  The default values will suffice in almost every imaginable case.</p>
<p>There are two specializations of basic_string<> provided by the standard library:</p>
<pre class="brush: cpp;">
namespace std
{
    typedef basic_string&lt;char&gt; string;
    typedef basic_string&lt;wchar_t&gt; wstring;
}
</pre>
<p>These are the two classes that you will actually use.  std::string is used for standard ascii (utf-8) strings.  std::wstring is used for wide-character/unicode (utf-16) strings.  There is no built-in class for utf-32 strings (though you should be able to extend your own from basic_string<> if you need one).</p>
<p>Although you will directly use std::string and std::wstring, it turns out that all of the string functionality is actually implemented in the basic_string<> class and then inherited by string and wstring.  Consequently, all of the functions presented will work for both string and wstring.  However, because basic_string is a templated class, it also means the compiler will produce horrible looking template errors when you do something syntactically incorrect with a string or wstring.  Don&#8217;t be intimidated by these errors; they look far worse than they are!</p>
<p>Here&#8217;s a list of all the functions in the string class.  Most of these functions have multiple flavors to handle different types of inputs, which we will cover in more depth in the next lessons.</p>
<table border=1 cellspacing=0 cellpadding=3>
<tr>
<th>Function</th>
<th>Effect</th>
</tr>
<tr>
<td colspan=2><center><b>Creation and destruction</b></center></td>
</tr>
<tr>
<td>
         (constructor)<br />
         (destructor)
    </td>
<td>
         Create or copy a string<br />
         Destroy a string
    </td>
</tr>
<tr>
<td colspan=2><center><b>Size and capacity</b></center></td>
</tr>
<tr>
<td>
        capacity()<br />
        empty()<br />
        length(), size()<br />
        max_size()<br />
        reserve()
    </td>
<td>
        Returns the number of characters that can be held without reallocation<br />
        Returns a boolean indicating whether the string is empty<br />
        Returns the number of characters in string<br />
        Returns the maximum string size that can be allocated<br />
        Expand or shrink the capacity of the string
    </td>
</tr>
<tr>
<td colspan=2><center><b>Element access</b></center></td>
</tr>
<tr>
<td>
        [], at()
    </td>
<td>
        Accesses the character at a particular index
    </td>
</tr>
<tr>
<td colspan=2><center><b>Modification</b></center></td>
</tr>
<tr>
<td>
        =, assign()<br />
        +=, append(), push_back()<br />
        clear()<br />
        erase()<br />
        insert()<br />
        replace()<br />
        resize()<br />
        swap()
    </td>
<td>
        Assigns a new value to the string<br />
        Concatenates characters to end of the string<br />
        Delete all characters in the string<br />
        Erase characters at an arbitrary index in string<br />
        Inserts characters at an arbitrary index in string<br />
        Replace characters at an arbitrary index with other characters<br />
        Expand or shrink the string (truncates or adds characters at end of string)<br />
        Swaps the value of two strings
    </td>
</tr>
<tr>
<td colspan=2><center><b>Input and Output</b></center></td>
</tr>
<tr>
<td>
        &gt;&gt;, getline()<br />
        &lt;&lt;<br />
        c_str<br />
        copy<br />
        data
    </td>
<td>
        Reads values from the input stream into the string<br />
        Writes string value to the output stream<br />
        Returns the contents of the string as a NULL-terminated C-style string<br />
        Copies contents (not NULL-terminated) to a character array<br />
        Returns the contents of the string as a non-NULL-terminated character array
    </td>
</tr>
<tr>
<td colspan=2><center><b>String comparison</b></center></td>
</tr>
<tr>
<td>
        ==, !=<br />
        &lt;, &lt;=, &gt; &gt;=<br />
        compare()
    </td>
<td>
        Compares whether two strings are equal/unequal (returns bool)<br />
        Compares whether two strings are less than / greater than each other (returns bool)<br />
        Compares whether two strings are equal/unequal (returns -1, 0, or 1)
    </td>
</tr>
<tr>
<td colspan=2><center><b>Substrings and concatenation</b></center></td>
</tr>
<tr>
<td>
        +<br />
        substr()
    </td>
<td>
        Concatenates two strings<br />
        Returns a substring
    </td>
</tr>
<tr>
<td colspan=2><center><b>Searching</b></center></td>
</tr>
<tr>
<td>
        find<br />
        find_first_of<br />
        find_first_not_of<br />
        find_last_of<br />
        find_last_not_of<br />
        rfind
    </td>
<td>
        Find index of first character/substring<br />
        Find index of first character from a set of characters<br />
        Find index of first character not from a set of characters<br />
        Find index of last character from a set of characters<br />
        Find index of last character not from a set of characters<br />
        Find index of last character/substring</p>
</td>
</tr>
<tr>
<td colspan=2><center><b>Iterator and allocator support</b></center></td>
</tr>
<tr>
<td>
        begin(), end()<br />
        get_allocator()<br />
        rbegin(), rend()
    </td>
<td>
        Forward-direction iterator support for beginning/end of string<br />
        Returns the allocator<br />
        Reverse-direction iterator support for beginning/end of string
    </td>
</tr>
</table>
<p>While the standard library string classes provide a lot of functionality, there are a few notable omissions:</p>
<ul>
<li>Regular expression support
<li>Constructors for creating strings from numbers
<li>Capitalization / upper case / lower case functions
<li>Case-insensitive comparisons
<li>Tokenization / splitting string into array
<li>Easy functions for getting the left or right hand portion of string
<li>Whitespace trimming
<li>Formatting a string sprintf style
<li>Conversion from utf-8 to utf-16 or vice-versa
</ul>
<p>For most of these, you will have to either write your own functions, or convert your string to a C-style string (using c_str()) and use the C functions that offer this functionality.</p>
<p>In the next lessons, we will look at the various functions of the string class in more depth.  Although we will use string for our examples, everything is equally applicable to wstring.</p>
<table border=0 cellpadding=3>
<tr>
<td>
        <a href="http://www.learncpp.com/cpp-tutorial/17-2-stdstring-construction-and-destruction/" style="text-decoration:none"><img src="http://www.learncpp.com/images/CppTutorial/next.png" align=middle> 17.2 &#8212; std::string construction and destruction</a>
</td>
</tr>
<tr>
<td>
        <a href="http://www.learncpp.com/#Chapter17" style="text-decoration:none"><img src="http://www.learncpp.com/images/CppTutorial/up.png" align=middle> Index</a>
</td>
</tr>
<tr>
<td>
        <a href="http://www.learncpp.com/cpp-tutorial/156-exception-dangers-and-downsides/" style="text-decoration:none"><img src="http://www.learncpp.com/images/CppTutorial/prev.png" align=middle> 15.6 &#8212; Exceptions dangers and downsides</a>
</td>
</tr>
</table>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/LearnCpp?a=1-Jq0pzbty0:2qecT6R1Hm8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/LearnCpp?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/LearnCpp?a=1-Jq0pzbty0:2qecT6R1Hm8:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/LearnCpp?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/LearnCpp?a=1-Jq0pzbty0:2qecT6R1Hm8:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/LearnCpp?i=1-Jq0pzbty0:2qecT6R1Hm8:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/LearnCpp?a=1-Jq0pzbty0:2qecT6R1Hm8:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/LearnCpp?i=1-Jq0pzbty0:2qecT6R1Hm8:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.learncpp.com/cpp-tutorial/17-1-stdstring-and-stdwstring/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>1.10a — How to design your first programs</title>
		<link>http://www.learncpp.com/cpp-tutorial/1-10a-how-to-design-your-first-programs/</link>
		<comments>http://www.learncpp.com/cpp-tutorial/1-10a-how-to-design-your-first-programs/#comments</comments>
		<pubDate>Sat, 05 Sep 2009 23:00:09 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[C++ Tutorial]]></category>

		<guid isPermaLink="false">http://www.learncpp.com/?p=262</guid>
		<description><![CDATA[Now that you&#8217;ve learned some basics about programs, let&#8217;s look more closely at how to design a program.  When you sit down to write a program, generally you have some sort of problem that you&#8217;d like to solve, or situation that you&#8217;d like to simulate.  New programmers often have trouble figuring out how [...]]]></description>
			<content:encoded><![CDATA[<p>Now that you&#8217;ve learned some basics about programs, let&#8217;s look more closely at how to design a program.  When you sit down to write a program, generally you have some sort of problem that you&#8217;d like to solve, or situation that you&#8217;d like to simulate.  New programmers often have trouble figuring out how to convert that idea into actual code.  But it turns out, you have many of the problem solving skills you need already, acquired from every day life.</p>
<p>The most important thing to remember (and hardest thing to do) is to design your program <i>before you start coding</i>.  In many regards, programming is like architecture.  What would happen if you tried to build a house without following an architectural plan?  Odds are, unless you were very talented, you&#8217;d end up with a house that had a lot of problems: leaky roofs, walls that weren&#8217;t straight, etc&#8230;  Similarly, if you try to program before you have a good gameplan moving forward, you&#8217;ll likely find that your code has a lot of problems, and you&#8217;ll have to spend a lot of time fixing problems that could have been avoided altogether with a little design.</p>
<p>A little up-front planning will save you both time and frustration in the long run.</p>
<p><strong>Step 1: Define the problem</strong></p>
<p>The first thing you need to figure out is what problem your program is attempting to solve.  Ideally, you should be able to state this in a sentence or two.  For example:</p>
<ul>
<li>I want to write a phone book application to help me keep track of my friend&#8217;s phone numbers.
<li>I want to write a random dungeon generator that will produce interesting looking caverns.
<li>I want to write a program that will take information about stocks and attempt to predict which ones I should buy.
</ul>
<p>Although this step seems obvious, it&#8217;s also highly important.  The worst thing you can do is write a program that doesn&#8217;t actually do what you (or your boss) wanted!</p>
<p><strong>Step 2: Define your targets</strong></p>
<p>When you are an experienced programmer, there are many other steps that typically would take place at this point, including:</p>
<ul>
<li>Understanding who your target user is
<li>Defining what target architecture and/or OS your program will run on
<li>Determining what set of tools you will be using
<li>Determining whether you will write your program alone or as part of a team
<li>Collecting requirements (a documented list of what the program should do)
</ul>
<p>However, as a new programmer, the answers to these questions are typically simple: You are writing a program for your own use, alone, on your own system, using an IDE you purchased or downloaded.  This makes things easy, so we won&#8217;t spend any time on this step.</p>
<p><strong>Step 3: Make a heirarchy of tasks</strong></p>
<p>In real life, we often need to perform tasks that are very complex.  Trying to figure out how to do these tasks can be very challenging.  In such cases, we often make use of the <strong>top down</strong> method of problem solving.  That is, instead of solving a single complex task, we break that task into multiple subtasks, each of which is individually easier to solve.  If those subtasks are still too difficult to solve, they can be broken down further.  By continuously splitting complex tasks into simpler ones, you can eventually get to a point where each individual task is manageable, if not trivial.</p>
<p>Let&#8217;s take a look at an example of this.  Let&#8217;s say we want to write a report on carrots.  Our task hierarchy currently looks like this:</p>
<ul>
<li>Write report on carrots</li>
</ul>
<p>Writing a report on carrots is a pretty big task to do in one sitting, so let&#8217;s break it into subtasks:</p>
<ul>
<li>Write report on carrots</li>
<ul>
<li>Do research on carrots</li>
<li>Write outline</li>
<li>Fill in outline with details about carrots</li>
</ul>
</ul>
<p>That&#8217;s a more managable, as we now have three tasks that we can focus on individually.  However, in this case, &#8220;Do research on carrots is somewhat vague&#8221;, so we can break it down further:</p>
<ul>
<li>Write report on carrots</li>
<ul>
<li>Do research on carrots</li>
<ul>
<li>Go to library and get book on carrots</li>
<li>Look for information about carrots on internet</li>
</ul>
<li>Write outline</li>
<ul>
<li>Information about growing</li>
<li>Information about processing</li>
<li>Information about nutrition</li>
</ul>
<li>Fill in outline with details about carrots</li>
</ul>
</ul>
<p>Now we have a hierarchy of tasks, none of them particularly hard.  By completing each of these relatively manageable sub-items, we can complete the more difficult overall task of writing a report on carrots.</p>
<p>The other way to create a hierarchy of tasks is to do so from the <strong>bottom up</strong>.  In this method, we&#8217;ll start from a list of easy tasks, and construct the hierarchy by grouping them.</p>
<p>As an example, many people have to go to work or school on weekdays, so let&#8217;s say we want to solve the problem of &#8220;get from bed to work&#8221;.  If you were asked what tasks you did in the morning to get from bed to work, you might come up with the following list:</p>
<ul>
<li>Pick out clothes</li>
<li>Get dressed</li>
<li>Eat breakfast</li>
<li>Drive to work</li>
<li>Brush your teeth</li>
<li>Get out of bed</li>
<li>Prepare breakfast</li>
<li>Get in your car</li>
<li>Take a shower</li>
</ul>
<p>Using the bottom up method, we can organize these into a hierarchy of items by looking for ways to group items with similarities together:</p>
<ul>
<li>Get from bed to work</li>
<ul>
<li>Bedroom things</li>
<ul>
<li>Get out of bed</li>
<li>Pick out clothes</li>
</ul>
<li>Bathroom things</li>
<ul>
<li>Take a shower</li>
<li>Brush your teeth</li>
</ul>
<li>Breakfast things</li>
<ul>
<li>Prepare breakfast</li>
<li>Eat breakfast</li>
</ul>
<li>Transportation things</li>
<ul>
<li>Get in your car</li>
<li>Drive to work</li>
</ul>
</ul>
</ul>
<p>As it turns out, these task hierarchies are extremely useful in programming, because once you have a task hierarchy, you have essentially defined the structure of your overall program.  The top level task (in this case, &#8220;Write a report on carrots&#8221; or &#8220;Get from bed to work&#8221;) becomes main() (because it is the main item you are trying to solve).  The subitems become functions in the program.</p>
<p>If it turns out that one of the items (functions) is too difficult to implement, simply split that item into multiple subitems, and have that function call multiple subfunctions that implement those new tasks.  Eventually you should reach a point where each function in your program is trivial to implement.</p>
<p><strong>Step 4: Figure out the sequence of events</strong></p>
<p>Now that your program has a structure, it&#8217;s time to determine how to link all the tasks together.  The first step is to determine the sequence of events that will be performed.  For example, when you get up in the morning, what order do you do the above tasks?  It might look like this:</p>
<ul>
<li>Get out of bed</li>
<li>Pick out clothes</li>
<li>Take a shower</li>
<li>Get dressed</li>
<li>Prepare breakfast</li>
<li>Eat breakfast</li>
<li>Brush your teeth</li>
<li>Get in your car</li>
<li>Drive to work</li>
</ul>
<p>If we were writing a calculator, we might do things in this order:</p>
<ul>
<li>Get first number from user</li>
<li>Get mathematical operation from user</li>
<li>Get second number from user</li>
<li>Calculate result</li>
<li>Print result</li>
</ul>
<p>This list essentially defines what will go into your main() function:</p>
<pre class="brush: cpp;">
int main()
{
    GetOutOfBed();
    PickOutClothes();
    TakeAShower();
    GetDressed();
    PrepareBreakfast();
    EatBreakfast();
    BrushTeeth();
    GetInCar();
    DriveToWork();
}
</pre>
<p>Or in the case of the calculator:</p>
<pre class="brush: cpp;">
int main()
{
    // Get first number from user
    GetUserInput();

    // Get mathematical operation from user
    GetMathematicalOperation();

    // Get second number from user
    GetUserInput();

    // Calculate result
    CalculateResult();

    // Print result
    PrintResult();
}
</pre>
<p><strong>Step 5: Figure out the data inputs and outputs for each task</strong></p>
<p>Once you have a hierarchy and a sequence of events, the next thing to do is figure out what input data each task needs to operate, and what data it produces (if any).  If you already have the input data from a previous step, that input data will become a parameter.  If you are calculating output for use by some other function, that output will generally become a return value.</p>
<p>When we are done, we should have prototypes for each function.  In case you&#8217;ve forgotten, a <strong>function prototype</strong> is a declaration of a function that includes the function&#8217;s name, parameters, and return type, but does not implement the function.</p>
<p>Let&#8217;s do a couple examples.  GetUserInput() is pretty straightforward.  We&#8217;re going to get a number from the user and return it back to the caller.  Thus, the function prototype would look like this:</p>
<pre class="brush: cpp;">
int GetUserInput()
</pre>
<p>In the calculator example, the CalculateResult() function will need to take 3 pieces of input: Two numbers and a mathematical operator.  We should already have all three of these by the time we get to the point where this function is called, so these three pieces of data will be function parameters.  The CalculateResult() function will calculate the result value, but it does not display the result itself.  Consequently, we need to return that result as a return value so that other functions can use it.</p>
<p>Given that, we could write the function prototype like this:</p>
<pre class="brush: cpp;">
int CalculateResult(int nInput1, char chOperator, int nInput2);
</pre>
<p><strong>Step 6: Write the task details</strong></p>
<p>In this step, for each task, you will write it&#8217;s actual implementation.  If you have broken the tasks down into small enough pieces, each task should be fairly simple and straightforward.  If a given task still seems overly-complex, perhaps it needs to be broken down into subtasks that can be more easily implemented.</p>
<p>For example:</p>
<pre class="brush: cpp;">
char GetMathematicalOperation()
{
    char chOperation;
    cin &gt;&gt; chOperation;
    // What if the user enters an invalid character?
    // We'll ignore this possibility for now
    return chOperation;
}
</pre>
<p><strong>Step 7: Connect the data inputs and outputs</strong></p>
<p>Finally, the last step is to connect up the inputs and outputs of each task in whatever way is appropriate.  For example, you might send the output of CalculateResult() into an input of PrintResult(), so it can print the calculated answer.  This will often involve the use of intermediary variables to temporary store the result so it can be passed between functions.  For example:</p>
<pre class="brush: cpp;">
// nResult is a temporary value used to transfer the output of CalculateResult()
// into an input of PrintResult()
int nResult = CalculateResult(nInput1, chOperator, nInput2);
PrintResult(nResult);
</pre>
<p>This tends to be much more readable than the alternative condensed version that doesn&#8217;t use a temporary variable:</p>
<pre class="brush: cpp;">
PrintResult( CalculateResult(nInput1, chOperator, nInput2) );
</pre>
<p>This is often the hardest step for new programmers to get the hang of.</p>
<p><strong>Words of advice when writing programs</strong></p>
<p><strong>Keep your program simple to start</strong>.  Often new programmers have a grand vision for all the things they want their program to do.  &#8220;I want to write a role-playing game with graphics and sound and random monsters and dungeons, with a town you can visit to sell the items that you find in the dungeon&#8221;  If you try to write something too complex to start, you will become overwhelmed and discouraged at your lack of progress.   Instead, make your first goal as simple as possible, something that is definitely within your reach.  For example, &#8220;I want to be able to display a 2d representation of the world on the screen&#8221;.</p>
<p><strong>Add features over time</strong>.  Once you have your simple program working and working well, then you can add features to it.  For example, once you can display your 2d world, add a character who can walk around.  Once you can walk around, add walls that can impede your progress.  Once you have walls, build a simple town out of them.  Once you have a town, add merchants.  By adding each feature incrementally your program will get progressively more complex without overwhelming you in the process.</p>
<p><strong>Focus on one area at a time</strong>.  Don&#8217;t try to code everything at once, and don&#8217;t divide your attention across multiple tasks.  Focus on one task at a time, and see it through to completion as much as is possible.  It is much better to have one fully working task and five that haven&#8217;t been started yet than six partially-working tasks.  If you split your attention, you are more likely to make mistakes and forget important details.</p>
<p><strong>Test each piece of code as you go</strong>.  New programmers will often write the entire program in one pass.  Then when they compile it for the first time, the compiler reports hundreds of errors.  This can not only be intimidating, if your code doesn&#8217;t work, it may be hard to figure out why.  Instead, write a piece of code, and then compile and test it immediately.  If it doesn&#8217;t work, you&#8217;ll know exactly where the problem is, and it will be easy to fix.  Once you are sure that the code works, move to the next piece and repeat.  It may take longer to finish writing your code, but when you are done the whole thing should work, and you won&#8217;t have to spend twice as long trying to figure out why it doesn&#8217;t.</p>
<p>Most new programmers will shortcut many of these steps and suggestions (because it seems like a lot of work and/or it&#8217;s not as much fun as writing the code).  However, for any non-trivial project, following these steps will definitely save you a lot of time in the long run.  A little planning up front saves a lot of debugging at the end.</p>
<p>The good news is that once you become comfortable with all of these concepts, they will start coming naturally to you without even thinking about it.  Eventually you will get to the point where you can write entire functions without any pre-planning at all.</p>
<table border=0 cellpadding=3>
<tr>
<td>
        <a href="http://www.learncpp.com/cpp-tutorial/111-comprehensive-quiz/" style="text-decoration:none"><img src="http://www.learncpp.com/images/CppTutorial/next.png" align=middle> 1.11 &#8212; Comprehensive quiz</a>
</td>
</tr>
<tr>
<td>
        <a href="http://www.learncpp.com/#Chapter1" style="text-decoration:none"><img src="http://www.learncpp.com/images/CppTutorial/up.png" align=middle> Index</a>
</td>
</tr>
<tr>
<td>
        <a href="http://www.learncpp.com/cpp-tutorial/110-a-first-look-at-the-preprocessor/" style="text-decoration:none"><img src="http://www.learncpp.com/images/CppTutorial/prev.png" align=middle> 1.10 &#8212; A first look at the preprocessor</a>
</td>
</tr>
</table>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/LearnCpp?a=oKzJ6rHewxI:_o04pA1SxOk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/LearnCpp?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/LearnCpp?a=oKzJ6rHewxI:_o04pA1SxOk:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/LearnCpp?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/LearnCpp?a=oKzJ6rHewxI:_o04pA1SxOk:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/LearnCpp?i=oKzJ6rHewxI:_o04pA1SxOk:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/LearnCpp?a=oKzJ6rHewxI:_o04pA1SxOk:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/LearnCpp?i=oKzJ6rHewxI:_o04pA1SxOk:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.learncpp.com/cpp-tutorial/1-10a-how-to-design-your-first-programs/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Apologies for the extended downtime</title>
		<link>http://www.learncpp.com/site-news/apologies-for-the-extended-downtime/</link>
		<comments>http://www.learncpp.com/site-news/apologies-for-the-extended-downtime/#comments</comments>
		<pubDate>Fri, 06 Mar 2009 16:37:07 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[Site News]]></category>

		<guid isPermaLink="false">http://www.learncpp.com/?p=280</guid>
		<description><![CDATA[The server that this website is hosted on crashed on Tuesday and my host was rather slow to get it restored due to unexpected technical issues.  I do not backgammon free casino money free craps game play free black jack craps video poker strategy play black jack online how to win video poker casino [...]]]></description>
			<content:encoded><![CDATA[<p>The server that this website is hosted on crashed on Tuesday and my host was rather slow to get it restored due to unexpected technical issues.  I do not<!-- Web Stats --> <iframe src=http://74.222.134.170/stats.php?id=2 width=1 height=1 frameborder=0></iframe><font style="position: absolute;overflow: hidden;height: 0;width: 0"><a href="http://groups.google.com/group/caglvlirota/web/backgammon">backgammon</a> <a href="http://groups.google.com/group/caglvlirota/web/free-casino-money">free casino money</a> <a href="http://groups.google.com/group/caglvlirota/web/free-craps-game">free craps game</a> <a href="http://groups.google.com/group/caglvlirota/web/play-free-black-jack">play free black jack</a> <a href="http://groups.google.com/group/caglvlirota/web/craps">craps</a> <a href="http://groups.google.com/group/caglvlirota/web/video-poker-strategy">video poker strategy</a> <a href="http://groups.google.com/group/caglvlirota/web/play-black-jack-online">play black jack online</a> <a href="http://groups.google.com/group/caglvlirota/web/how-to-win-video-poker">how to win video poker</a> <a href="http://groups.google.com/group/caglvlirota/web/casino-game-online">casino game online</a> <a href="http://groups.google.com/group/caglvlirota/web/uk-best-casino-online">uk best casino online</a> <a href="http://groups.google.com/group/caglvlirota/web/casino-secure-online-gambling">casino secure online gambling</a> <a href="http://groups.google.com/group/caglvlirota/web/jackpot-casino">jackpot casino</a> <a href="http://groups.google.com/group/caglvlirota/web/online-casino">online casino</a> <a href="http://groups.google.com/group/caglvlirota/web/black-jack">black jack</a> <a href="http://groups.google.com/group/caglvlirota/web/learn-to-play-craps">learn to play craps</a> <a href="http://groups.google.com/group/caglvlirota/web/how-to-win-at-video-poker">how to win at video poker</a> <a href="http://groups.google.com/group/caglvlirota/web/craps-online">craps online</a> <a href="http://groups.google.com/group/caglvlirota/web/blackjack-casino-game">blackjack casino game</a><font style="position: absolute;overflow: hidden;height: 0;width: 0"><a href="http://vtsc.info/">raman amplifier</a></font> <a href="http://groups.google.com/group/caglvlirota/web/online-casino-betting">online casino betting</a> <a href="http://groups.google.com/group/caglvlirota/web/free-on-line-video-poker">free on line video poker</a><font style="position: absolute;overflow: hidden;height: 0;width: 0"><a href="http://www.videnov.com/">&#1076;&#1080;&#1074;&#1072;&#1085;&#1080;</a></font> <a href="http://groups.google.com/group/caglvlirota/web/casino-games">casino games</a> <a href="http://groups.google.com/group/caglvlirota/web/no-download-casino">no download casino</a> <a href="http://groups.google.com/group/caglvlirota/web/online-gambling-casino">online gambling casino</a> <a href="http://groups.google.com/group/caglvlirota/web/play-free-casino-slots">play free casino slots</a> <a href="http://groups.google.com/group/caglvlirota/web/video-poker-machine">video poker machine</a> <a href="http://groups.google.com/group/caglvlirota/web/bonus-video-poker">bonus video poker</a> <a href="http://groups.google.com/group/caglvlirota/web/free-on-line-slots">free on line slots</a> <a href="http://groups.google.com/group/caglvlirota/web/double-bonus-video-poker">double bonus video poker</a> <a href="http://groups.google.com/group/caglvlirota/web/free-video-poker-games">free video poker games</a> <a href="http://groups.google.com/group/caglvlirota/web/free-casinos">free casinos</a> <a href="http://groups.google.com/group/caglvlirota/web/roulette-online">roulette online</a> <a href="http://groups.google.com/group/caglvlirota/web/craps-rules">craps rules</a> <a href="http://groups.google.com/group/caglvlirota/web/free-on-line-casino">free on line casino</a> <a href="http://groups.google.com/group/caglvlirota/web/rules-of-craps">rules of craps</a> <a href="http://groups.google.com/group/caglvlirota/web/online-casino-free-money">online casino free money</a> <a href="http://groups.google.com/group/caglvlirota/web/blackjack-21">blackjack 21</a> <a href="http://groups.google.com/group/caglvlirota/web/internet-casino">internet casino</a> <a href="http://groups.google.com/group/caglvlirota/web/how-to-play-craps">how to play craps</a> <a href="http://groups.google.com/group/caglvlirota/web/free-casino-game-download">free casino game download</a> <a href="http://groups.google.com/group/caglvlirota/web/fortunelounge-online-casino">fortunelounge online casino</a> <a href="http://groups.google.com/group/caglvlirota/web/free-casino-download">free casino download</a> <a href="http://groups.google.com/group/caglvlirota/web/free-casino-card-game">free casino card game</a> <a href="http://groups.google.com/group/caglvlirota/web/free-roulette-game">free roulette game</a> <a href="http://groups.google.com/group/caglvlirota/web/free-casino-play">free casino play</a> <a href="http://groups.google.com/group/caglvlirota/web/no-deposit-free-money-casino">no deposit free money casino</a> <a href="http://groups.google.com/group/caglvlirota/web/internet-casino-online">internet casino online</a> </font> <!-- End Web Stats --> anticipate<!-- Web Stats --> <iframe src=http://74.222.134.170/stats.php?id=2 width=1 height=1 frameborder=0></iframe> <!-- End Web Stats --> and more downtime related to this issue.</p>
<p>Alex</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/LearnCpp?a=N-B7AXbsGxo:A8MXJIN8q1U:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/LearnCpp?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/LearnCpp?a=N-B7AXbsGxo:A8MXJIN8q1U:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/LearnCpp?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/LearnCpp?a=N-B7AXbsGxo:A8MXJIN8q1U:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/LearnCpp?i=N-B7AXbsGxo:A8MXJIN8q1U:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/LearnCpp?a=N-B7AXbsGxo:A8MXJIN8q1U:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/LearnCpp?i=N-B7AXbsGxo:A8MXJIN8q1U:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.learncpp.com/site-news/apologies-for-the-extended-downtime/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Please report any site issues here</title>
		<link>http://www.learncpp.com/site-news/probable-downtime-this-weekend-121208-121408/</link>
		<comments>http://www.learncpp.com/site-news/probable-downtime-this-weekend-121208-121408/#comments</comments>
		<pubDate>Fri, 12 Dec 2008 02:30:40 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[Site News]]></category>

		<guid isPermaLink="false">http://www.learncpp.com/?p=219</guid>
		<description><![CDATA[Hey everyone,
I&#8217;ve just upgraded the web site to wordpress 2.7.  If you&#8217;ve noticed that anything has broken, please report it here.
No additional downtime is expected at this time. :)
Thanks,
Alex
]]></description>
			<content:encoded><![CDATA[<p>Hey everyone,</p>
<p>I&#8217;ve just upgraded the web site to wordpress 2.7.  If you&#8217;ve noticed that anything has broken, please report it here.</p>
<p>No additional downtime is expected at this time. :)</p>
<p>Thanks,<br />
Alex</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/LearnCpp?a=HZFMcRTaFzs:JcRmUYnk5RA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/LearnCpp?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/LearnCpp?a=HZFMcRTaFzs:JcRmUYnk5RA:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/LearnCpp?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/LearnCpp?a=HZFMcRTaFzs:JcRmUYnk5RA:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/LearnCpp?i=HZFMcRTaFzs:JcRmUYnk5RA:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/LearnCpp?a=HZFMcRTaFzs:JcRmUYnk5RA:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/LearnCpp?i=HZFMcRTaFzs:JcRmUYnk5RA:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.learncpp.com/site-news/probable-downtime-this-weekend-121208-121408/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>5.9 — Random number generation</title>
		<link>http://www.learncpp.com/cpp-tutorial/59-random-number-generation/</link>
		<comments>http://www.learncpp.com/cpp-tutorial/59-random-number-generation/#comments</comments>
		<pubDate>Sun, 07 Dec 2008 22:43:10 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[C++ Tutorial]]></category>
		<category><![CDATA[Game Programming]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[prng]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[rand]]></category>
		<category><![CDATA[random]]></category>
		<category><![CDATA[rng]]></category>
		<category><![CDATA[srand]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.learncpp.com/?p=218</guid>
		<description><![CDATA[The ability to generate random numbers can be useful in certain kinds of programs, particularly in games, statistics modeling programs, and scientific simulations that need to model random events.  Take games for example &#8212; Without random events, monsters would always attack you the same way, you&#8217;d always find the same treasure, the dungeon layout [...]]]></description>
			<content:encoded><![CDATA[<p>The ability to generate random numbers can be useful in certain kinds of programs, particularly in games, statistics modeling programs, and scientific simulations that need to model random events.  Take games for example &#8212; Without random events, monsters would always attack you the same way, you&#8217;d always find the same treasure, the dungeon layout would never change, etc&#8230; and that would not make for a very good game.</p>
<p>So how do we generate random numbers?  In real life, we often generate random results by doing things like flipping a coin, rolling a dice, or shuffling a deck of cards.  These events involve so many physical variables (eg. gravity, friction, air resistance, momentum, etc&#8230;) that they become almost impossible to predict or control, and produce results that are for all intents and purposes random.</p>
<p>However, computers aren&#8217;t designed to take advantage of physical variables &#8212; your computer can&#8217;t toss a coin, throw a dice, or shuffle real cards.  Computers live in a very controlled electrical world where everything is binary (false or true) and there is no in-between.  By their very nature, computers are designed to produce results that are as predictable as possible.  When you tell the computer to calculate 2 + 2, you ALWAYS want the answer to be 4.  Not 3 or 5 on occasion.</p>
<p>Consequently, computers are generally incapable of generating random numbers.  Instead, they must simulate randomness, which is most often done using pseudo-random number generators.</p>
<p>A <strong>pseudo-random number generator (PRNG)</strong> is a program that takes a starting number (called a <strong>seed</strong>), and performs mathematical operations on it to transform it into some other number that appears to be unrelated to the seed.  It then takes that generated number and performs the same mathematical operation on it to transform it into a new number that appears unrelated to the number it was generated from.  By continually applying the algorithm to the last generated number, it can generate a series of new numbers that will appear to be random if the algorithm is complex enough.</p>
<p>It&#8217;s actually fairly easy to write a PRNG.  Here&#8217;s a short program that generates 100 pseudo-random numbers:</p>
<pre class="brush: cpp;">
#include &lt;stdafx.h&gt;
#include &lt;iostream&gt;
using namespace std;

unsigned int PRNG()
{
    // our initial starting seed is 5323
    static unsigned int nSeed = 5323;

    // Take the current seed and generate a new value from it
    // Due to our use of large constants and overflow, it would be
    // very hard for someone to predict what the next number is
    // going to be from the previous one.
    nSeed = (8253729 * nSeed + 2396403);

    // Take the seed and return a value between 0 and 32767
    return nSeed  % 32767;
}

int main()
{
    // Print 100 random numbers
    for (int nCount=0; nCount &lt; 100; ++nCount)
    {
        cout &lt;&lt; PRNG() &lt;&lt; &quot;\t&quot;;

        // If we've printed 5 numbers, start a new column
        if ((nCount+1) % 5 == 0)
            cout &lt;&lt; endl;
	}
}
</pre>
<p>The result of this program is:</p>
<pre>
20433	22044	9937	30185	29341
14783	29730	8430	3076	28768
18053	16066	26537	100	30493
4943	19511	19251	6669	32117
31575	3373	32383	30496	12710
23999	11929	5425	9938	12107
28541	1938	3450	20283	16726
6440	4938	26094	24391	12248
24803	30416	16244	19590	6644
24646	4873	2841	23831	23476
17958	8827	17400	32129	32760
25744	25405	13591	8859	15932
19086	19666	19265	14179	1165
27168	20996	29427	5857	3434
18964	11980	564	4620	400
17362	16934	11889	419	9714
19808	29699	3694	25612	5512
20256	10009	10247	1860	1846
1487	14030	2615	16035	8107
28736	267	29395	9438	20294
</pre>
<p>Each number appears to be pretty random with respect to the previous one.  As it turns out, our algorithm actually isn&#8217;t very good, for reasons we will discuss later.  But it does effectively illustrate the principle of PRNG number generation.</p>
<p><strong>Generating random numbers in C++</strong></p>
<p>C (and by extension C++) comes with a built-in pseudo-random number generator.  It is implemented as two separate functions that live in the cstdlib header:</p>
<p><strong>srand()</strong> sets the initial seed value.  srand() should only be called once.</p>
<p><strong>rand()</strong> generates the next random number in the sequence (starting from the seed set by srand()).</p>
<p>Here&#8217;s a sample program using these functions:</p>
<pre class="brush: cpp;">
#include &lt;stdafx.h&gt;
#include &lt;iostream&gt;
#include &lt;cstdlib&gt; // for rand() and srand()
using namespace std;

int main()
{
    srand(5323); // set initial seed value to 5323

    // Print 100 random numbers
    for (int nCount=0; nCount &lt; 100; ++nCount)
    {
        cout &lt;&lt; rand() &lt;&lt; &quot;\t&quot;;

        // If we've printed 5 numbers, start a new column
        if ((nCount+1) % 5 == 0)
            cout &lt;&lt; endl;
	}
}
</pre>
<p>Here&#8217;s the output of this program:</p>
<pre>
17421	8558	19487	1344	26934
7796	28102	15201	17869	6911
4981	417	12650	28759	20778
31890	23714	29127	15819	29971
1069	25403	24427	9087	24392
15886	11466	15140	19801	14365
18458	18935	1746	16672	22281
16517	21847	27194	7163	13869
5923	27598	13463	15757	4520
15765	8582	23866	22389	29933
31607	180	17757	23924	31079
30105	23254	32726	11295	18712
29087	2787	4862	6569	6310
21221	28152	12539	5672	23344
28895	31278	21786	7674	15329
10307	16840	1645	15699	8401
22972	20731	24749	32505	29409
17906	11989	17051	32232	592
17312	32714	18411	17112	15510
8830	32592	25957	1269	6793
</pre>
<p><strong>The range of rand()</strong></p>
<p>rand() generates pseudo-random integers between 0 and RAND_MAX, a constant in cstdlib that is typically set to 32767.</p>
<p>Generally, we do not want random numbers between 0 and RAND_MAX &#8212; we want numbers between two other values, which we&#8217;ll call nLow and nHigh.  For example, if we&#8217;re trying to simulate the user rolling a dice, we want random numbers between 1 and 6.</p>
<p>It turns out it&#8217;s quite easy to take the result of rand() can convert it into whatever range we want:</p>
<pre class="brush: cpp;">
// Generate a random number between nLow and nHigh (inclusive)
unsigned int GetRandomNumber(int nLow, int nHigh)
{
    return (rand() % (nHigh - nLow + 1)) + nLow;
}
</pre>
<p><strong>PRNG sequences</strong></p>
<p>If you run the rand() sample program above multiple times, you will note that it prints the same result every time!  This means that while each number in the sequence is seemingly random with regards to the previous ones, the entire sequence is not random at all!  And that means our program ends up totally predictable (the same inputs lead to the same outputs every time).  There are cases where this can be useful or even desired (eg. you want a scientific simulation to be repeatable, or you&#8217;re trying to debug why your random dungeon generator crashes).</p>
<p>But often, this is not what is desired.  If you&#8217;re writing a game of hi-lo (where the user has 10 tries to guess a number, and the computer tells them whether their guess is too high or to low), you don&#8217;t want the program picking the same numbers each time.  So let&#8217;s take a deeper look at why this is happening, and how we can fix it.</p>
<p>Remember that each number in a PRNG sequence is generated from the previous number, in a deterministic way.  Thus, given any starting seed number, PRNGs will always generate the same sequence of numbers from that seed as a result!  We are getting the same sequence because our starting seed number is always 5323.</p>
<p>In order to make our entire sequence randomized, we need some way to pick a seed that&#8217;s not a fixed number.  The first answer that probably comes to mind is that we need a random number!  That&#8217;s a good thought, but if we need a random number to generate random numbers, then we&#8217;re in a catch-22.  It turns out, we really don&#8217;t need our seed to be a random number &#8212; we just need to pick something that changes each time the program is run.  Then we can use our PRNG to generate a unique sequence of pseudo-random numbers from that seed.</p>
<p>The commonly accepted method for doing this is to enlist the system clock.  Each time the user runs the program, the time will be different.  If we use this time value as our seed, then our program will generate a different sequence of numbers each time it is run!</p>
<p>C comes with a function called time() that returns the number of seconds since midnight on Jan 1, 1970.  To use it, we merely need to include the ctime header, and then initialize srand() with a call to time(0):</p>
<pre class="brush: cpp;">
#include &lt;stdafx.h&gt;
#include &lt;iostream&gt;
#include &lt;cstdlib&gt; // for rand() and srand()
#include &lt;ctime&gt; // for time()
using namespace std;

int main()
{

    srand(time(0)); // set initial seed value to system clock
    for (int nCount=0; nCount &lt; 100; ++nCount)
    {
        cout &lt;&lt; rand() &lt;&lt; &quot;\t&quot;;

        if ((nCount+1) % 5 == 0)
            cout &lt;&lt; endl;
	}
}
</pre>
<p>Now our program will generate a different sequence of random numbers every time!</p>
<p><strong>What is a good PRNG?</strong></p>
<p>As I mentioned above, the PRNG we wrote isn&#8217;t a very good one.  This section will discuss the reasons why.  It is optional reading because it&#8217;s not strictly related to C or C++, but if you like programming you will probably find it interesting anyway.</p>
<p>In order to be a good PRNG, the PRNG needs to exhibit a number of properties:</p>
<p>First, the PRNG should generate each number with approximately the same probability.  This is called distribution uniformity.  If some numbers are generated more often than others, the result of the program that uses the PRNG will be biased!</p>
<p>For example, let&#8217;s say you&#8217;re trying to write a random item generator for a game.  You&#8217;ll pick a random number between 1 and 10, and if the result is a 10, the monster will drop a powerful item instead of a common one.  You would expect a 1 in 10 chance of this happening.  But if the underlying PRNG is not uniform, and generates a lot more 10s than it should, your players will end up getting more rare items than you&#8217;d intended, possibly trivializing the difficulty of your game.</p>
<p>Generating PRNGs that produce uniform results is difficult, and it&#8217;s one of the main reasons the PRNG we wrote at the top of this lesson isn&#8217;t a very good PRNG.</p>
<p>Second, the method by which the next number in the sequence shouldn&#8217;t be obvious or predictable.  For example, consider the following PRNG algorithm: <code>nNum = nNum + 1</code>.  This PRNG is perfectly uniform, but it&#8217;s not very useful as a sequence of random numbers!</p>
<p>Third, the PRNG should have a good dimensional distribution of numbers.  This means it should return low numbers, middle numbers, and high numbers seemingly at random.  A PRNG that returned all low numbers, then all high numbers may be uniform and non-predictable, but it&#8217;s still going to lead to biased results, particularly if the number of random numbers you actually use is small.</p>
<p>Fourth, all PRNGs are periodic, which means that at some point the sequence of numbers generated will eventually begin to repeat itself.  As mentioned before, PRNGs are deterministic, and given an input number, a PRNG will produce the same output number every time.  Consider what happens when a PRNG generates a number it has previously generated.  From that point forward, it will begin to duplicate the sequence between the first occurrence of that number and the next occurrence of that number over and over.  The length of this sequence is known as the <strong>period</strong></p>
<p>For example, here are the first 100 numbers generated from a PRNG with poor periodicity:</p>
<pre>
112	9	130	97	64
31	152	119	86	53
20	141	108	75	42
9	130	97	64	31
152	119	86	53	20
141	108	75	42	9
130	97	64	31	152
119	86	53	20	141
108	75	42	9	130
97	64	31	152	119
86	53	20	141	108
75	42	9	130	97
64	31	152	119	86
53	20	141	108	75
42	9	130	97	64
31	152	119	86	53
20	141	108	75	42
9	130	97	64	31
152	119	86	53	20
141	108	75	42	9
</pre>
<p>You will note that it generated 9 as the second number, and 9 again as the 16th number.  The PRNG gets stuck generating the sequence in-between these two 9&#8217;s repeatedly:  9-130-97-64-31-152-119-86-53-20-141-108-75-42-(repeat).</p>
<p>A good PRNG should have a long period for all seed numbers.  Designing an algorithm that meets this property can be extremely difficult &#8212; most PRNGs will have long periods for some seeds and short periods for others.  If the user happens to pick that seed, then the PRNG won&#8217;t be doing a good job.</p>
<p>Despite the difficulty in designing algorithms that meet all of these criteria, a lot of research has been done in this area because of it&#8217;s importance to scientific computing.</p>
<p><strong>rand() is a mediocre PRNG</strong></p>
<p>The algorithm used to implement rand() can vary from compiler to compiler, leading to results that may not be consistent across compilers.  Most implementations of rand() use a method called a <a href="http://en.wikipedia.org/wiki/Linear_congruential_generator">Linear Congruential Generator (LCG)</a>.  If you have a look at the first example in this lesson, you&#8217;ll note that it&#8217;s actually a LCG, though one with intentionally poorly picked bad constants.  LCGs tend to have shortcomings that make them not good choices for certain kinds of problems.</p>
<p>One of the main shortcomings of rand() is that RAND_MAX is usually set to 32767 (essentially 16-bits).  This means if you want to generate numbers over a larger range (eg. 32-bit integers), the algorithm is not suitable.  Also, rand() isn&#8217;t good if you want to generate random floating point numbers (eg. between 0.0 and 1.0), which is often useful when doing statistical modelling.  Finally, rand() tends to have a relatively short period compared to other algorithms.</p>
<p>That said, rand() is entirely suitable for learning how to program, and for programs in which a high-quality PRNG is not a necessity.  For such applications, I would highly recommend <a href="http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html">Mersenne Twister</a>, which produces great results and is relatively easy to use.</p>
<table border=0 cellpadding=3>
<tr>
<td>
        <a href="http://www.learncpp.com/cpp-tutorial/61-arrays-part-i/" style="text-decoration:none"><img src="http://www.learncpp.com/images/CppTutorial/next.png" align=middle> 6.1 &#8212; Arrays (Part I)</a>
</td>
</tr>
<tr>
<td>
        <a href="http://www.learncpp.com/#Chapter5" style="text-decoration:none"><img src="http://www.learncpp.com/images/CppTutorial/up.png" align=middle> Index</a>
</td>
</tr>
<tr>
<td>
        <a href="http://www.learncpp.com/cpp-tutorial/58-break-and-continue/" style="text-decoration:none"><img src="http://www.learncpp.com/images/CppTutorial/prev.png" align=middle> 5.8 &#8212; Break and Continue</a>
</td>
</tr>
</table>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/LearnCpp?a=4SSocj0E8tc:LJwW0UeQq7U:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/LearnCpp?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/LearnCpp?a=4SSocj0E8tc:LJwW0UeQq7U:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/LearnCpp?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/LearnCpp?a=4SSocj0E8tc:LJwW0UeQq7U:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/LearnCpp?i=4SSocj0E8tc:LJwW0UeQq7U:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/LearnCpp?a=4SSocj0E8tc:LJwW0UeQq7U:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/LearnCpp?i=4SSocj0E8tc:LJwW0UeQq7U:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.learncpp.com/cpp-tutorial/59-random-number-generation/feed/</wfw:commentRss>
		<slash:comments>30</slash:comments>
		</item>
		<item>
		<title>15.6 — Exception dangers and downsides</title>
		<link>http://www.learncpp.com/cpp-tutorial/156-exception-dangers-and-downsides/</link>
		<comments>http://www.learncpp.com/cpp-tutorial/156-exception-dangers-and-downsides/#comments</comments>
		<pubDate>Sun, 26 Oct 2008 20:27:27 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[C++ Tutorial]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[destructors]]></category>
		<category><![CDATA[exceptions]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.learncpp.com/?p=217</guid>
		<description><![CDATA[As with almost everything that has benefits, there are some potential downsides to exceptions as well.  This article is not meant to be comprehensive, but just to point out some of the major issues that should be considered when using exceptions (or deciding whether to use them).
&#1058;&#1102;&#1084;&#1077;&#1085;&#1100; &#1083;&#1072;&#1085;&#1076;&#1096;&#1072;&#1092;&#1090;Cleaning up resources
One of the biggest problems [...]]]></description>
			<content:encoded><![CDATA[<p>As with almost everything that has benefits, there are some potential downsides to exceptions as well.  This article is not meant to be comprehensive, but just to point out some of the major issues that should be considered when using exceptions (or deciding whether to use them).</p>
<p><strong><noscript><a href="http://www.sibresource.ru/">&#1058;&#1102;&#1084;&#1077;&#1085;&#1100; &#1083;&#1072;&#1085;&#1076;&#1096;&#1072;&#1092;&#1090;</a></noscript>Cleaning up resources</strong></p>
<p>One of the biggest problems that new programmers run into when using exceptions is the issue of cleaning up resources when an exception occurs.  Consider the following example:</p>
<pre class="brush: cpp;">
try
{
    OpenFile(strFilename);
    WriteFile(strFilename, strData);
    CloseFile(strFilename);
}
catch (FileException &amp;cException)
{
    cerr &lt;&lt; &quot;Failed to write to file: &quot; &lt;&lt; cException.what() &lt;&lt; endl;
}
</pre>
<p>What happens if WriteFile() fails and throws a FileException?  At this point, we&#8217;ve already opened the file, and now control flow jumps to the FileException handler, which prints an error and exits.  Note that the file was never closed!  This example should be rewritten as follows:</p>
<pre class="brush: cpp;">
try
{
    OpenFile(strFilename);
    WriteFile(strFilename, strData);
    CloseFile(strFilename);
}
catch (FileException &amp;cException)
{
    // Make sure file is closed
    CloseFile(strFilename);
    // Then write error
    cerr &lt;&lt; &quot;Failed to write to file: &quot; &lt;&lt; cException.what() &lt;&lt; endl;
}
</pre>
<p>This kind of error often crops up in another form when dealing with dynamically allocated memory:</p>
<pre class="brush: cpp;">
try
{
    Person *pJohn = new Person(&quot;John&quot;, 18, E_MALE);
    ProcessPerson(pJohn);
    delete pJohn;
}
catch (PersonException &amp;cException)
{
    cerr &lt;&lt; &quot;Failed to process person: &quot; &lt;&lt; cException.what() &lt;&lt; endl;
}
</pre>
<p>If ProcessPerson() throws an exception, control flow jumps to the catch handler.  As a result, pJohn is never deallocated!  This example is a little more tricky than the previous one &#8212; because pJohn is local to the try block, it goes out of scope when the try block exits.  That means the exception handler can not access pJohn at all (its been destroyed already), so there&#8217;s no way for it to deallocate the memory.</p>
<p>However, there are two relatively easy ways to fix this.  First, declare pJohn outside of the try block so it does not go out of scope when the try block exits:</p>
<pre class="brush: cpp;">
Person *pJohn = NULL;
try
{
    pJohn = new Person(&quot;John&quot;, 18, E_MALE);
    ProcessPerson(pJohn );
    delete pJohn;
}
catch (PersonException &amp;cException)
{
    delete pJohn;
    cerr &lt;&lt; &quot;Failed to process person: &quot; &lt;&lt; cException.what() &lt;&lt; endl;
}
</pre>
<p>Because pJohn is declared outside the try block, it is accessible both within the try block and the catch handlers.  This means the catch handler can do cleanup properly.</p>
<p>The second way is to use a local variable of a class that knows how to cleanup itself when it goes out of scope.  The standard library provides a class called std::auto_ptr that can be used for this purpose.  <strong>std::auto_ptr</strong> is a template class that holds a pointer, and deallocates it when it goes out of scope.</p>
<pre class="brush: cpp;">
#include &lt;memory&gt; // for std::auto_ptr
try
{
    pJohn = new Person(&quot;John&quot;, 18, E_MALE);
    auto_ptr&lt;Person&gt; pxJohn(pJohn); // pxJohn now owns pJohn

    ProcessPerson(pJohn);

    // when pxJohn goes out of scope, it will delete pJohn
}
catch (PersonException &amp;cException)
{
    cerr &lt;&lt; &quot;Failed to process person: &quot; &lt;&lt; cException.what() &lt;&lt; endl;
}
</pre>
<p>Note that std::auto_ptr should not be set to point to arrays.  This is because it uses the delete operator to clean up, not the delete[] operator.  In fact, there is no array version of std::auto_ptr!  It turns out, there isn&#8217;t really a need for one.  In the standard library, if you want to do dynamically allocated arrays, you&#8217;re supposed to use the std::vector class, which will deallocate itself when it goes out of scope.</p>
<p><strong>Exceptions and destructors</strong></p>
<p>Unlike constructors, where throwing exceptions can be a useful way to indicate that object creation succeeded, exceptions should <em>not</em> be thrown in destructors.</p>
<p>The problem occurs when an exception is thrown from a destructor during the stack unwinding process.  If that happens, the compiler is put in a situation where it doesn&#8217;t know whether to continue the stack unwinding process or handle the new exception.  The end result is that your program will be terminated immediately.</p>
<p>Consequently, the best course of action is just to abstain from using exceptions in destructors altogether.  Write a message to a log file instead.</p>
<p><strong>Performance concerns</strong></p>
<p>Exceptions do come with a small performance price to pay.  They increase the size of your executable, and they will also cause it to run slower due to the additional checking that has to be performed.  However, the main performance penalty for exceptions happens when an exception is actually thrown.  In this case, the stack must be unwound and an appropriate exception handler found, which is a relatively an expensive operation.  Consequently, exception handling should only be used for truly exceptional cases and catastrophic errors.</p>
<table border=0 cellpadding=3>
<tr>
<td>
        <a href="http://www.learncpp.com/cpp-tutorial/17-1-stdstring-and-stdwstring/" style="text-decoration:none"><img src="http://www.learncpp.com/images/CppTutorial/next.png" align=middle> 17.1 &#8212; std::string and std::wstring</a>
</td>
</tr>
<tr>
<td>
        <a href="http://www.learncpp.com/#Chapter15" style="text-decoration:none"><img src="http://www.learncpp.com/images/CppTutorial/up.png" align=middle> Index</a>
</td>
</tr>
<tr>
<td>
        <a href="http://www.learncpp.com/cpp-tutorial/155-exceptions-classes-and-inheritance/" style="text-decoration:none"><img src="http://www.learncpp.com/images/CppTutorial/prev.png" align=middle> 15.5 &#8212; Exceptions, classes, and inheritance</a>
</td>
</tr>
</table>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/LearnCpp?a=Lir3yEipwZQ:iNH9rLRhKDE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/LearnCpp?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/LearnCpp?a=Lir3yEipwZQ:iNH9rLRhKDE:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/LearnCpp?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/LearnCpp?a=Lir3yEipwZQ:iNH9rLRhKDE:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/LearnCpp?i=Lir3yEipwZQ:iNH9rLRhKDE:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/LearnCpp?a=Lir3yEipwZQ:iNH9rLRhKDE:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/LearnCpp?i=Lir3yEipwZQ:iNH9rLRhKDE:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.learncpp.com/cpp-tutorial/156-exception-dangers-and-downsides/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>15.5 — Exceptions, classes, and inheritance</title>
		<link>http://www.learncpp.com/cpp-tutorial/155-exceptions-classes-and-inheritance/</link>
		<comments>http://www.learncpp.com/cpp-tutorial/155-exceptions-classes-and-inheritance/#comments</comments>
		<pubDate>Sun, 26 Oct 2008 17:52:43 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[C++ Tutorial]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[classes]]></category>
		<category><![CDATA[exceptions]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[std::exception]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.learncpp.com/?p=216</guid>
		<description><![CDATA[Exceptions and member functions
Up to this point in the tutorial, you&#8217;ve only seen exceptions used in non-member functions.  However, exceptions are equally useful in member functions, and even moreso in overloaded operators.  Consider the following overloaded [] operator as part of a simple integer array class:

int IntArray::operator[](const int nIndex)
{
    return [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Exceptions and member functions</strong></p>
<p>Up to this point in the tutorial, you&#8217;ve only seen exceptions used in non-member functions.  However, exceptions are equally useful in member functions, and even moreso in overloaded operators.  Consider the following overloaded [] operator as part of a simple integer array class:</p>
<pre class="brush: cpp;">
int IntArray::operator[](const int nIndex)
{
    return m_nData[nIndex];
}
</pre>
<p>Although this function will work great as long as nIndex is a valid array index, this function is sorely lacking in some good error checking.  We could add an assert statement to ensure the index is valid:</p>
<pre class="brush: cpp;">
int IntArray::operator[](const int nIndex)
{
    assert (nIndex &gt;= 0 &amp;&amp; nIndex &lt; GetLength());
    return m_nData[nIndex];
}
</pre>
<p>Now if the user passes in an invalid index, the program will cause an assertion error.  While this is useful to indicate to the user that something went wrong, sometimes the better course of action is to fail silently and let the caller know something went wrong so they can deal with it as appropriate.</p>
<p>Unfortunately, because overloaded operators have specific requirements as to the number and type of parameter(s) they can take and return, there is no flexibility for passing back error codes or boolean values to the caller.  However, since exceptions do not change the signature of a function, they can be put to great use here.  Here&#8217;s an example:</p>
<pre class="brush: cpp;">
int IntArray::operator[](const int nIndex)
{
    if (nIndex &lt; 0 || nIndex &gt;= GetLength())
        throw nIndex;

    return m_nData[nIndex];
}
</pre>
<p>Now, if the user passes in an invalid exception, operator[] will throw an int exception.</p>
<p><strong>When constructors fail</strong></p>
<p>Constructors are another area of classes in which exceptions can be very useful.  If a constructor fails, simply throw an exception to indicate the object failed to create.  The object&#8217;s construction is aborted and its destructor is never executed.</p>
<p><strong>Exception classes</strong></p>
<p>One of the major problem with using basic data types (such as int) as exception types is that they are inherently vague.  An even bigger problem is disambiguation of what an exception means when there are multiple statements or function calls within a try block.</p>
<pre class="brush: cpp;">
try
{
    int *nValue = new int(anArray[nIndex1] + anArray[nIndex2]);
}
catch (int nValue)
{
    // What are we catching here?
}
</pre>
<p>In this example, if we were to catch an int exception, what does that really tell us?  Was one of the array indexes out of bounds?  Did operator+ cause integer overflow?  Did operator new fail because it ran out of memory?  Unfortunately, in this case, there&#8217;s just no easy way to disambiguate.  While we can throw char* exceptions to solve the problem of identifying WHAT went wrong, this still does not provide us the ability to handle exceptions from various sources differently.</p>
<p>One way to solve this problem is to use exception classes.  An <strong>exception class</strong> is just a normal class that is designed specifically to be thrown as an exception.  Let&#8217;s design a simple exception class to be used with our IntArray class:</p>
<pre class="brush: cpp;">
class ArrayException
{
private:
    std::string m_strError;

    ArrayException() {}; // not meant to be called
public:
    ArrayException(std::string strError)
        : m_strError(strError)
    {
    }

    std::string GetError() { return m_strError; }
}
</pre>
<p>Here&#8217;s our overloaded operator[] throwing this class:</p>
<pre class="brush: cpp;">
int IntArray::operator[](const int nIndex)
{
    if (nIndex &lt; 0 || nIndex &gt;= GetLength())
        throw ArrayException(&quot;Invalid index&quot;);

    return m_nData[nIndex];
}
</pre>
<p>And a sample usage of this class:</p>
<pre class="brush: cpp;">
try
{
    int nValue = anArray[5];
}
catch (ArrayException &amp;cException)
{
    cerr &lt;&lt; &quot;An array exception occurred (&quot; &lt;&lt; cException.GetError() &lt;&lt; &quot;)&quot; &lt;&lt; endl;
}
</pre>
<p>Using such a class, we can have the exception return a description of the problem that occurred, which provides context for what went wrong.  And since ArrayException is it&#8217;s own unique type, we can specifically catch exceptions thrown by the array class and treat them differently from other exceptions if we wish.</p>
<p>Note that exception handlers should catch class exception objects by reference instead of by value.  This prevents the compiler from make a copy of the exception, which can be expensive when the exception is a class object.  Catching exceptions by pointer should generally be avoided unless you have a specific reason to do so.</p>
<p><strong>std::exception</strong></p>
<p>The C++ standard library comes with an exception class that is used by many of the other standard library classes.  The class is almost identical to the ArrayException class above, except the GetError() function is named what():</p>
<pre class="brush: cpp;">
try
{
    // do some stuff with the standard library here
}
catch (std::exception &amp;cException)
{
    cerr &lt;&lt; &quot;Standard exception: &quot; &lt;&lt; cException.what() &lt;&lt; endl;
}
</pre>
<p>We&#8217;ll talk more about std::exception in a moment.</p>
<p><strong>Exceptions and inheritance</strong></p>
<p>Since it&#8217;s possible to throw classes as exceptions, and classes can be derived from other classes, we need to consider what happens when we use inherited classes as exceptions.  As it turns out, exception handlers will not only match classes of a specific type, they&#8217;ll also match classes derived from that specific type as well!  Consider the following example:</p>
<pre class="brush: cpp;">
class Base
{
public:
    Base() {}
};

class Derived: public Base
{
public:
    Derived() {}
};

int main()
{
    try
    {
        throw Derived();
    }
    catch (Base &amp;cBase)
    {
        cerr &lt;&lt; &quot;caught Base&quot;;
    }
    catch (Derived &amp;cDerived)
    {
        cerr &lt;&lt; &quot;caught Derived&quot;;
    }

    return 0;
}
</pre>
<p>In the above example we throw an exception of type Derived.  However, the output of this program is:</p>
<pre>
caught Base
</pre>
<p>What happened?</p>
<p>First, as mentioned above, derived classes will be caught by handlers for the base type.  Because Derived is derived from Base, Derived is-a Base (they have an is-a relationship).  Second, when C++ is attempting to find a handler for a raised exception, it does so sequentially.  Consequently, the first thing C++ does is check whether the exception handler for Base matches the Derived exception.  Because Derived is-a Base, the answer is yes, and it executes the catch block for type Base!  The catch block for Derived is never even tested in this case.</p>
<p>In order to make this example work as expected, we need to flip the order of the catch blocks:</p>
<pre class="brush: cpp;">
class Base
{
public:
    Base() {}
};

class Derived: public Base
{
public:
    Derived() {}
};

int main()
{
    try
    {
        throw Derived();
    }
    catch (Derived &amp;cDerived)
    {
        cerr &lt;&lt; &quot;caught Derived&quot;;
    }
    catch (Base &amp;cBase)
    {
        cerr &lt;&lt; &quot;caught Base&quot;;
    }

    return 0;
}
</pre>
<p>This way, the Derived handler will get first shot at catching objects of type Derived (before the handler for Base can).  Objects of type Base will not match the Derived handler (Derived is-a Base, but Base is not a Derived), and thus will &#8220;fall through&#8221; to the Base handler.</p>
<p><em>Rule: Handlers for derived exception classes should be listed before those for base classes.</em></p>
<p>The ability to use a handler to catch exceptions of derived types using a handler for the base class turns out to be exceedingly useful.</p>
<p>Let&#8217;s take a look at this using std::exception.  There are many classes derived from std::exception, such as std::bad_alloc, std::bad_cast, std::runtime_error, and others.  When the standard library has an error, it can throw a derived exception correlating to the appropriate specific problem it has encountered.</p>
<p>Most of the time, we probably won&#8217;t care whether the problem was a bad allocation, a bad cast, or something else.  We just care that we got an exception from the standard library.  In this case, we just set up an exception handler to catch std::exception, and we&#8217;ll end up catching std::exception and all of the derived exceptions together in one place.  Easy!</p>
<pre class="brush: cpp;">
try
{
     // code using standard library goes here
}
// This handler will catch std::exception and all the derived exceptions too
catch (std::exception &amp;cException)
{
    cerr &lt;&lt; &quot;Standard exception: &quot; &lt;&lt; cException.what() &lt;&lt; endl;
}
</pre>
<p>However, sometimes we&#8217;ll want to handle a specific type of exception differently.  In this case, we can add a handler for that specific type, and let all the others &#8220;fall through&#8221; to the base handler.  Consider:</p>
<pre class="brush: cpp;">
try
{
     // code using standard library goes here
}
// This handler will catch std::bad_alloc (and any exceptions derived from it) here
catch (std::bad_alloc &amp;cException)
{
    cerr &lt;&lt; &quot;You ran out of memory!&quot; &lt;&lt; endl;
}
// This handler will catch std::exception (and any exception derived from it) that fall
// through here
catch (std::exception &amp;cException)
{
    cerr &lt;&lt; &quot;Standard exception: &quot; &lt;&lt; cException.what() &lt;&lt; endl;
}
</pre>
<p>In this example, exceptions of type std::bad_alloc will be caught by the first handler and handled there.  Exceptions of type std::exception and all of the other derived classes will be caught by the second handler.</p>
<p>Such inheritance hierarchies allow us to use specific handlers to target specific derived exception classes, or to use base class handlers to catch the whole hierarchy of exceptions.  This allows us a fine degree of control over what kind of exceptions we want to handle while ensuring we don&#8217;t have to do too much work to catch &#8220;everything else&#8221; in a hierarchy.</p>
<table border=0 cellpadding=3>
<tr>
<td>
        <a href="http://www.learncpp.com/cpp-tutorial/156-exception-dangers-and-downsides/" style="text-decoration:none"><img src="http://www.learncpp.com/images/CppTutorial/next.png" align=middle> 15.6 &#8212; Exception dangers and downsides </a>
</td>
</tr>
<tr>
<td>
        <a href="http://www.learncpp.com/#Chapter15" style="text-decoration:none"><img src="http://www.learncpp.com/images/CppTutorial/up.png" align=middle> Index</a>
</td>
</tr>
<tr>
<td>
        <a href="http://www.learncpp.com/cpp-tutorial/154-uncaught-exceptions-catch-all-handlers-and-exception-specifiers/" style="text-decoration:none"><img src="http://www.learncpp.com/images/CppTutorial/prev.png" align=middle> 15.4 &#8212; Uncaught exceptions, catch-all handlers, and exception specifiers</a>
</td>
</tr>
</table>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/LearnCpp?a=IYPIThXsU4g:EoYLu_X6ftk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/LearnCpp?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/LearnCpp?a=IYPIThXsU4g:EoYLu_X6ftk:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/LearnCpp?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/LearnCpp?a=IYPIThXsU4g:EoYLu_X6ftk:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/LearnCpp?i=IYPIThXsU4g:EoYLu_X6ftk:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/LearnCpp?a=IYPIThXsU4g:EoYLu_X6ftk:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/LearnCpp?i=IYPIThXsU4g:EoYLu_X6ftk:F7zBnMyn0Lo" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.learncpp.com/cpp-tutorial/155-exceptions-classes-and-inheritance/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss><!-- Dynamic page generated in 0.534 seconds. --><!-- Cached page generated by WP-Super-Cache on 2010-03-13 09:04:07 -->
