Professional Documents
Culture Documents
1
Before You Ask........................................................................................................................48
When You Ask..........................................................................................................................49
When asking about code...........................................................................................................51
Don't post homework questions................................................................................................52
Follow up with a brief note on the solution..............................................................................52
How To Interpret Answers........................................................................................................52
How To Answer Questions in a Helpful Way..........................................................................53
Published by EliteHussar
Last update on Aug 20, 2010 at 6:10am UTC
Pointers and references look different enough (pointers use the “*” and “->” operators,
references use “.“), but they seem to do similar things. Both pointers and references let
you refer to other objects indirectly. How, then, do you decide when to use one and not
the other?
First, recognize that there is no such thing as a null reference. A reference must always
refer to some object. As a result, if you have a variable whose purpose is to refer to
another object, but it is possible that there might not be an object to refer to, you should
make the variable a pointer, because then you can set it to null. On the other hand, if the
variable must always refer to an object, i.e., if your design does not allow for the
possibility that the variable is null, you should probably make the variable a reference.
“But wait,” you wonder, “what about underhandedness like this?”
1 char *pc = 0; // set pointer to null
2
2 char& rc = *pc; // make reference refer to
3 // dereferenced null pointer
Well, this is evil, pure and simple. The results are undefined (compilers can generate
output to do anything they like), and people who write this kind of code should be
shunned until they agree to cease and desist. If you have to worry about things like this
in your software, you’re probably best off avoiding references entirely. Either that or
finding a better class of programmers to work with. We’ll henceforth ignore the
possibility that a reference can be “null.”
Because a reference must refer to an object, C++ requires that references be initialized:
1 string& rs; // error! References must
2 // be initialized
3 string s("xyzzy");
4 string& rs = s; // okay, rs refers to s
The fact that there is no such thing as a null reference implies that it can be more
efficient to use references than to use pointers. That’s because there’s no need to test the
validity of a reference before using it:
1 void printDouble(const double& rd)
2{
3 cout << rd; // no need to test rd; it
4} // must refer to a double
3
2{
3 if (pd) { // check for null pointer
4 cout << *pd;
5}
6}
Another important difference between pointers and references is that pointers may be
reassigned to refer to different objects. A reference, however, always refers to the object
with which it is initialized:
1 string s1("Nancy");
2 string s2("Clancy");
3 string& rs = s1; // rs refers to s1
4
5 string *ps = &s1; // ps points to s1<a name="31186"></a>
6
rs = s2; // rs still refers to s1,
7
// but s1's value is now
8
// "Clancy"
9
10 ps = &s2; // ps now points to s2;
11 // s1 is unchanged
12
In general, you should use a pointer whenever you need to take into account the
possibility that there’s nothing to refer to (in which case you can set the pointer to null)
or whenever you need to be able to refer to different things at different times (in which
case you can change where the pointer points). You should use a reference whenever you
know there will always be an object to refer to and you also know that once you’re
referring to that object, you’ll never want to refer to anything else.
4
There is one other situation in which you should use a reference, and that’s when you’re
implementing certain operators. The most common example is operator[]. This operator
typically needs to return something that can be used as the target of an assignment:
1 vector<int> v(10); // create an int vector of size 10;
2 // vector is a template in the
3 // standard C++ library
4 v[5] = 10; // the target of this assignment is
5 // the return value of operator[]
If operator[] returned a pointer, this last statement would have to be written this way:
*v[5] = 10;
But this makes it look like v is a vector of pointers, which it’s not. For this reason, you’ll
almost always want operator[] to return a reference.
References, then, are the feature of choice when you know you have something to refer
to, when you’ll never want to refer to anything else, and when implementing operators
whose syntactic requirements make the use of pointers undesirable. In all other cases,
stick with pointers.
Published by chrisname
Last update on Jun 3, 2010 at 7:10pm UTC
Note: This article is a work in progress but if you do read it, please feel free to PM your
improvements to me. Thanks.
The Difference
5
People often confuse the difference between a 'compiler' and an 'IDE', which I guess is
born from the fact that most IDEs come with a compiler.
Compilers
A compiler is a program which takes source code written by a programmer and creates
an executable file.
A compiler, then, must create assembly code from the source code given and pass it to
the assembler. The assembler creates object code from the assembly code and then
passes the object files on to the linker. The linker finally creates the exectuable file that
you can run.
IDEs
IDE can either stand for Integrated Drive Electronics (which is a totally irrelevant (and
far more complicated) topic) or Integrated Development Environment.
An IDE is a program or (more usually) a group of programs which are used for program
development. An IDE usually consists of a syntax-highlighting text editor and a lot of
buttons and toolbars and such to help you to write code efficiently.
IDEs often come bundled with a compiler suite as well as a debugger and some have
more advanced features such as find-and-replace and auto-completion.
6
Comparisons
Compilers
There are many popular compilers, among them the GNU Compiler Collection (GCC)
which includes gcc and g++ (the GNU C Compiler and GNU C++ Compiler) and
Microsoft's Visual C and Visual C++ compilers. There are many other compilers of
varying qualities, such as the Borland C/C++ compilers, the Intel C++ compiler and the
[Open]Watcom Compilers. We will focus on gcc and Visual C in this article as they are
the most popular compilers.
gcc/g++
Note: gcc and g++ should not be capitalized (to distinguish gcc from GCC).
7
• Free -- a version of Visual C/C++ (which may or may not be crippleware) is
available for commercial use from Microsoft's website.
• Debugger -- Visual C/C++ is often acclaimed for it's powerful debugger.
Others
Other compilers also exist. Among these are OpenWatcom and the Intel C++ Compiler.
OpenWatcom is a cross-platform (Windows, MS-DOS, Linux and others) optimizing
compiler which can produce 16-bit code (something gcc cannot do). The Intel C++
compiler provides very thorough optimization.
IDEs
Errata
• Regarding Visual C/C++ -- This is now free for commercial use (thanks to PGP
Protector)
8
Book Of Brilliant Things
The list off books presented here are, in my experience, highly regarded in the
programming community. I do not present them in any order of merit, but I will try to
keep them in some logical order, by subject covered and experience level.
The Text about the books is cribbed from either the back cover of the book or Amazon's
description. I hope this does not cause a problem with copyright.
Contents:
• Subject: C++
o Beginner books
o Intermediate and expert books
• Subject: Algorithms and Data Structures
o Beginner books
o Intermediate and expert books
9
Subject: C++
Beginner books
Programming: Principles and Practice Using C++
by Bjarne Stroustrup
The book assumes that you aim eventually to write non-trivial programs, whether for
work in software development or in some other technical field.
The book explains fundamental concepts and techniques in greater depth than traditional
introductions. This approach will give you a solid foundation for writing useful, correct,
maintainable, and efficient code.
10
For Beginners–And Anyone Who Wants to Learn Something New
The book is primarily designed for people who have never programmed before, and it
has been tested with more than 1,000 first-year university students. However,
practitioners and advanced students will gain new insight and guidance by seeing how a
recognized master approaches the elements of his art.
The first half of the book covers a wide range of essential concepts, design and
programming techniques, language features, and libraries. Those will enable you to write
programs involving input, output, computation, and simple graphics. The second half
explores more specialized topics, such as text processing and testing, and provides
abundant reference material. Source code and support supplements are available from the
author’s website.
11
Throughout, the book does far more than merely describe every element of the language.
The focus is on showing how the language is used as a tool for design and programming,
and teaching the basic concepts programmers need to master C++. With this third
edition, Stroustrup has made the book even more accessible to those new to the language
while adding information and techniques that even expert C++ programmers will find
invaluable.
Exceptional C++
by Herb Sutter
Aimed at the experienced C++ programmer, Herb Sutter's ExceptionalC++ tests any
reader's knowledge of advanced C++ language features and idioms with several dozen
programming puzzles and explanations. This is a book that can definitely help bring your
C++ class design skills to the next level.
Based on the author's Guru of the Week Internet column, this book poses a series of
challenging questions on the inner workings of C++, centring around generic
programming with the Standard Template Library(STL), exception handling, memory
management and class design. Even if you think you know C++ well, most of these
problems will teach you something more about the language and how to write more
robust classes that are "exception safe". Don't think this is just "language lawyering"
though. The author's explanations stress sound programming principles (favouring
simplicity) and idioms (such as the Pimpl idiom for class design that promotes faster
compile times and better maintainability, or using "smart" auto_ptr's with STL.) Judging
from the range and depth of these examples, Sutter's command of the inner workings of
C++ is impressive and he does an excellent job at conveying this expertise without
jargon or a lot of theory.
12
After reading this book, C++ designers will learn several "best practices" at how to write
robust, efficient classes that are "exception safe" (meaning they don't throw any handled
exceptions and don't leak resources). Chances are you'll gain a better understanding of
memory management techniques and working with STL too. For the experienced
developer seeking leading-edge knowledge of some of the best ways to use C++,
ExceptionalC++ is both a challenging and truly worthwhile source of information.
--Richard Dragan, Amazon.com
More Exceptional C++ continues where Herb Sutter's best-selling Exceptional C++ left
off, delivering 40 puzzles that illuminate the most challenging -- and most powerful --
aspects of C++. More Exceptional C++ offers many new puzzles focused on generic
programming and the C++ Standard Template Library, including important techniques
such as traits and predicates, as well as key considerations in using standard containers
and algorithms -- many of them never covered elsewhere. More Exceptional C++
contains a detailed new section (and two appendices) on optimization in single- and
multithreaded environments. It also provides important new insights on crucial topics
first introduced in Exceptional C++, including exception safety, generic programming,
and memory management. For all C++ programmers.
Software "style" is about finding the perfect balance between overhead and
functionality... elegance and maintainability... flexibility and excess. In Exceptional C++
Style, legendary C++ guru Herb Sutter presents 40 new programming scenarios designed
13
to analyze not only the what but the why and help you find just the right balance in your
software.
Organized around practical problems and solutions, this book offers new insight into
crucial C++ details and interrelationships, and new strategies for today's key C++
programming techniques--including generic programming, STL, exception safety, and
more. You'll find answers to questions like:
• What can you learn about library design from the STL itself?
• How do you avoid making templated code needlessly non-generic?
• Why shouldn't you specialize function templates? What should you do instead?
• How does exception safety go beyond try and catch statements?
• Should you use exception specifications, or not?
• When and how should you "leak" the private parts of a class?
• How do you make classes safer for versioning?
• What's the real memory cost of using standard containers?
• How can using const really optimize your code?
• How does writing inline affect performance?
• When does code that looks wrong actually compile and run perfectly, and why
should you care?
• What's wrong with the design of std::string?
Exceptional C++ Style will help you design, architect, and code with style--and achieve
greater robustness and performance in all your C++ software.
C++ Coding Standards: Rules, Guidelines, and Best Practices by Herb Sutter
Consistent, high-quality coding standards improve software quality, reduce time-to-
market, promote teamwork, eliminate time wasted on inconsequential matters, and
simplify maintenance. Now, two of the world's most respected C++ experts distill the
14
rich collective experience of the global C++ community into a set of coding standards
that every developer and development team can understand and use as a basis for their
own coding standards.
The authors cover virtually every facet of C++ programming: design and coding style,
functions, operators, class design, inheritance, construction/destruction, copying,
assignment, namespaces, modules, templates, generality, exceptions, STL containers and
algorithms, and more. Each standard is described concisely, with practical examples.
From type definition to error handling, this book presents C++ best practices, including
some that have only recently been identified and standardized-techniques you may not
know even if you've used C++ for years. Along the way, you'll find answers to questions
like
15
Whether you're working alone or with others, C++ Coding Standards will help you write
cleaner code--and write it faster, with fewer hassles and less frustration.
The C++ Standard Library provides a set of common classes and interfaces that greatly
extend the core C++ language. Josuttis' book not only provides comprehensive
documentation of each library component, it also offers clearly written explanations of
complex concepts, describes the practical programming details needed for effective use,
and gives example after example of working code. This thoroughly up-to-date book
reflects the newest elements of the C++ standard library incorporated into the full
ANSI/ISO C++ language standard. In particular, the text focuses on the Standard
16
Template Library (STL), examining containers, iterators, function objects, and STL
algorithms.
C++ Templates begins with an insightful tutorial on basic concepts and language
features. The remainder of the book serves as a comprehensive reference, focusing first
on language details, then on a wide range of coding techniques, and finally on advanced
applications for templates. Examples used throughout the book illustrate abstract
concepts and demonstrate best practices.
Readers learn
17
The companion Web site at http://www.josuttis.com/tmplbook/ contains sample code and
additional updates.
Beginner books
Introduction to Algorithms
by TH Cormen
This title covers a broad range of algorithms in depth, yet makes their design and
analysis accessible to all levels of readers. Each chapter is relatively self-contained and
can be used as a unit of study. The algorithms are described in English and in a
pseudocode designed to be readable by anyone who has done a little programming. The
explanations have been kept elementary without sacrificing depth of coverage or
mathematical rigor. This second edition features new chapters on the role of algorithms,
probabilistic analysis and randomized algorithms, and linear programming, as well as
extensive revisions to virtually every section of the book. In a subtle but important
change, loop invariants are introduced early and used throughout the text to prove
algorithm correctness. Without changing the mathematical and analytic focus, the
authors have moved much of the mathematical foundations material from Part I to an
appendix and have included additional motivational material at the beginning.
by Donald E. Knuth
18
This multivolume work is widely recognized as the definitive description of classical
computer science. The first three volumes have for decades been an invaluable resource
in programming theory and practice for students, researchers, and practitioners alike.
The bible of all fundamental algorithms and the work that taught many of today's
software developers most of what they know about computer programming. --Byte,
September 1995
Countless readers have spoken about the profound personal influence of Knuth's work.
Scientists have marveled at the beauty and elegance of his analysis, while ordinary
programmers have successfully applied his "cookbook" solutions to their day-to-day
problems. All have admired Knuth for the breadth, clarity, accuracy, and good humor
found in his books.
I can't begin to tell you how many pleasurable hours of study and recreation they have
afforded me! I have pored over them in cars, restaurants, at work, at home! and even at a
Little League game when my son wasn't in the line-up. --Charles Long
Primarily written as a reference, some people have nevertheless found it possible and
interesting to read each volume from beginning to end.A programmer in China even
compared the experience to reading a poem.
If you think you're a really good programmer! read [Knuth's] Art of Computer
Programming! You should definitely send me a resume if you can read the whole thing.
--Bill Gates
19
Whatever your background, if you need to do any serious computer programming, you
will find your own good reason to make each volume in this series a readily accessible
part of your scholarly or professional library.
It's always a pleasure when a problem is hard enough that you have to get the Knuths off
the shelf. I find that merely opening one has a very useful terrorizing effect on
computers. --Jonathan Laventhol
For the first time in more than 20 years, Knuth has revised all three books to reflect more
recent developments in the field. His revisions focus specifically on those areas where
knowledge has converged since publication of the last editions, on problems that have
been solved, on problems that have changed. In keeping with the authoritative character
of these books, all historical information about previous work in the field has been
updated where necessary. Consistent with the author's reputation for painstaking
perfection, the rare technical errors in his work, discovered by perceptive and demanding
readers, have all been corrected. Hundreds of new exercises have been added to raise
new challenges.
Published by jsmith
Last update on Aug 20, 2010 at 7:42am UTC
20
A copy constructor is a special constructor for a class/struct that is used to make a copy
of an existing instance. According to the C++ standard, the copy constructor for MyClass
must have one of the following signatures:
Note that none of the following constructors, despite the fact that they could do the same
thing as a copy constructor, are copy constructors:
21
When do I need to write a copy constructor?
First, you should understand that if you do not declare a copy constructor, the
compiler gives you one implicitly. The implicit copy constructor does a
member-wise copy of the source object.
1 class MyClass {
2 int x;
3 char c;
4 std::string s;
5 };
In many cases, this is sufficient. However, there are certain circumstances where the
member-wise copy version is not good enough. By far, the most common reason the
default copy constructor is not sufficient is because the object contains raw pointers and
you need to take a "deep" copy of the pointer. That is, you don't want to copy the pointer
itself; rather you want to copy what the pointer points to. Why do you need to take
"deep" copies? This is typically because the instance owns the pointer; that is, the
22
instance is responsible for calling delete on the pointer at some point (probably the
destructor). If two objects end up calling delete on the same non-NULL pointer, heap
corruption results.
Rarely you will come across a class that does not contain raw pointers yet the default
copy constructor is not sufficient.
Const correctness
Why is this so important? There is a small clause in the C++ standard that says that non-
const references cannot bind to temporary objects.
A temporary object is an instance of an object that does not have a variable name. For
example:
is a temporary, because we have not given it a variable name. This is not a temporary:
23
std::string s( "Hello world" );
9 }
10
std::string hello( "Hello" );
11
12 print_me_bad( hello ); // Compiles ok; hello is not a temporary
13 print_me_bad( std::string( "World" ) ); // Compile error; temporary object
14 print_me_bad( "!" ); // Compile error; compiler wants to construct temporary
15 // std::string from const char*
16
17 print_me_good( hello ); // Compiles ok
18 print_me_good( std::string( "World" ) ); // Compiles ok
19 print_me_good( "!" ); // Compiles ok
20
24
Many of the STL containers and algorithms require that an object be copyable.
Typically, this means that you need to have the copy constructor that takes a const
reference, for the above reasons.
The assignment operator for a class is what allows you to use = to assign one instance to
another. For example:
There are actually several different signatures that an assignment operator can have:
25
(8) MyClass operator=( MyClass& rhs );
These signatures permute both the return type and the parameter type. While the return
type may not be too important, choice of the parameter type is critical.
(2), (5), and (8) pass the right-hand side by non-const reference, and is not
recommended. The problem with these signatures is that the following code would not
compile:
1 MyClass c1;
2 c1 = MyClass( 5, 'a', "Hello World" ); // assuming this constructor exists
This is because the right-hand side of this assignment expression is a temporary (un-
named) object, and the C++ standard forbids the compiler to pass a temporary object
through a non-const reference parameter.
This leaves us with passing the right-hand side either by value or by const reference.
Although it would seem that passing by const reference is more efficient than passing by
value, we will see later that for reasons of exception safety, making a temporary copy of
the source object is unavoidable, and therefore passing by value allows us to write fewer
lines of code.
26
First, you should understand that if you do not declare an assignment operator, the
compiler gives you one implicitly. The implicit assignment operator does member-wise
assignment of each data member from the source object. For example, using the class
above, the compiler-provided assignment operator is exactly equivalent to:
In general, any time you need to write your own custom copy constructor, you also need
to write a custom assignment operator.
A function which modifies some "global" state (for example, a reference parameter, or a
member function that modifies the data members of its instance) is said to be exception
safe if it leaves the global state well-defined in the event of an exception that is thrown at
any point during the function.
27
What does this really mean? Well, let's take a rather contrived (and trite) example. This
class wraps an array of some user-specified type. It has two data members: a pointer to
the array and a number of elements in the array.
9 };
1 template<>
2 MyArray<T>::operator=( const MyArray& rhs ) {
3 if( this != &rhs ) {
4 delete [] pElements;
5 pElements = new T[ rhs.numElements ];
6 for( size_t i = 0; i < rhs.numElements; ++i )
7 pElements[ i ] = rhs.pElements[ i ];
8 numElements = rhs.numElements;
9 }
10 return *this;
11 }
28
Well, not so fast. The problem is, the line
pElements[ i ] = rhs.pElements[ i ];
could throw an exception. This line invokes operator= for type T, which could be some
user-defined type whose assignment operator might throw an exception, perhaps an out-
of-memory (std::bad_alloc) exception or some other exception that the programmer of
the user-defined type created.
What would happen if it did throw, say on copying the 3rd element of 10 total? Well, the
stack is unwound until an appropriate handler is found. Meanwhile, what is the state of
our object? Well, we've reallocated our array to hold 10 T's, but we've copied only 2 of
them successfully. The third one failed midway, and the remaining seven were never
even attempted to be copied. Furthermore, we haven't even changed numElements, so
whatever it held before, it still holds. Clearly this instance will lie about the number of
elements it contains if we call count() at this point.
But clearly it was never the intent of MyArray's programmer to have count() give a
wrong answer. Worse yet, there could be other member functions that rely more heavily
(even to the point of crashing) on numElements being correct. Yikes -- this instance is
clearly a timebomb waiting to go off.
29
This implementation of operator= is not exception safe: if an exception is thrown during
execution of the function, there is no telling what the state of the object is; we can only
assume that it is in such a bad state (ie, it violates some of its own invariants) as to be
unusable. If the object is in a bad state, it might not even be possible to destroy the object
without crashing the program or causing MyArray to perhaps throw another exception.
And we know that the compiler runs destructors while unwinding the stack to search for
a handler. If an exception is thrown while unwinding the stack, the program necessarily
and unstoppably terminates.
The recommended way to write an exception safe assignment operator is via the copy-
swap idiom. What is the copy-swap idiom? Simply put, it is a two- step algorithm: first
make a copy, then swap with the copy. Here is our exception safe version of operator=:
1 template<>
2 MyArray<T>::operator=( const MyArray& rhs ) {
3 // First, make a copy of the right-hand side
4 MyArray tmp( rhs );
5
6 // Now, swap the data members with the temporary:
9
return *this;
10
}
11
30
Here's where the difference between exception handling and exception safety is
important: we haven't prevented an exception from occurring; indeed, the copy
construction of tmp from rhs may throw since it will copy T's. But, if the copy
construction does throw, notice how the state of *this has not changed, meaning that in
the face of an exception, we can guarantee that *this is still coherent, and furthermore,
we can even say that it is left unchanged.
But, you say, what about std::swap? Could it not throw? Yes and no. The default
std::swap<>, defined in <algorithm> can throw, since std::swap<> looks like this:
The first line runs the copy constructor of T, which can throw; the remaining lines are
assignment operators which can also throw.
HOWEVER, if you have a type T for which the default std::swap() may result in either
T's copy constructor or assignment operator throwing, you are politely required to
provide a swap() overload for your type that does not throw. [Since swap() cannot return
31
failure, and you are not allowed to throw, your swap() overload must always succeed.]
By requiring that swap does not throw, the above operator= is thus exception safe: either
the object is completely copied successfully, or the left-hand side is left unchanged.
Now you'll notice that our implementation of operator= makes a temporary copy as its
first line of code. Since we have to make a copy, we might as well let the compiler do
that for us automatically, so we can change the signature of the function to take the right-
hand side by value (ie, a copy) rather than by reference, and this allows us to eliminate
one line of code:
1 template<>
2 MyArray<T>::operator=( MyArray tmp ) {
3 std::swap( numElements, tmp.numElements );
4 std::swap( pElements, tmp.pElements );
5 return *this;
6 }
Published by firedraco
Last update on Aug 10, 2010 at 10:25pm UTC
This article will show you the common types of tags and how to use them.
Becomes:
1 int main() {
32
2 return 0;
3}
Use this whenever you post code, as it provides coloring most people are used to, as well
as preserving indentation (a Good Thing).
You can also make it start at a specific line number (10, in this example) by doing this:
[code firstline=10]//start in the middle of some function
for(unsigned int i = 0; i < 5; ++i) {
do_something(i);
}[/code]
This becomes:
10 //start in the middle of some function
11 for(unsigned int i = 0; i < 5; ++i) {
12 do_something(i);
13 }
One warning however, long code lines will simply stretch the box, so try to avoid using
overly long lines of code.
Becomes:
33
Code Output Goes Here
1234567890
Use this if you have output that you want to display from your code, e.g.: expected
results, actual results.
[code]int main() {
std::cout<<"Hello World!"<<std::endl;
return 0;
}
---
Hello World!
[/code]
Becomes:
1 int main() { Hello World!
2 std::cout<<"Hello World!"<<std::endl;
3 return 0;
4}
34
[quote=Somebody]I didn't say that!![/quote]
Becomes:
Quote goes here.
or
Somebody wrote:
I didn't say that!!
Use this to quote other people or stuff from another site. This makes it more obvious as
to what exactly was said.
[tt]abcdefghij 1234567890[/tt]
This tag is quite similar to the Code Output tag, shown above, except it does not have a
box surrounding it, and will delete excess whitespace at the beginning of a line.
This section contains the tags that simply alter the appearance of the text.
Underline:
35
[small]Text[/small] → Text
Subscript:
[sub]Text[/sub] → Text
Superscript:
[sup]Text[/sup] → Text
Published by Bazzy
Last update on Aug 22, 2010 at 11:42am UTC
Converting numbers to text and vice versa is a common issue as it can be useful in many
different situations and C++ doesn't provide a tool designed specifically to solve this
problem.
Luckily C++ is a general purpose language so it allows to solve this quite easily and, as
most things, you have many ways of accomplishing this task.
Here are listed some
Contents:
• C++ - stringstreams
o Number to String
Custom Formatting
36
o String to Number
o Simple Sample Functions
• C++ - boost library
• C - stdio
• C - stdlib
• Writing your own function
C++ - stringstreams
The C++ stream library is powerful and it allows easy formatted input output operations.
With stringstreams you can perform this input/output to string, this allows you to convert
numbers ( or any type with the << >> stream operators overloaded ) to and from strings.
With stringstreams you can use the same syntax to convert the different numeric types.
To use stringstreams you need to #include <sstream>
Number to String
Converting a number to a string takes two steps using stringstreams:
As with this conversion needs only output operation with the stream,
an ostringstream ( output string stream ) can be used instead of the stream for both input
and output ( stringstream )
37
5 ostringstream convert; // stream used for the conversion
6
7 convert << Number; // insert the textual representation of 'Number' in the
Then, since the << returns a reference to an ostream ( a base of ostringstream ) the result
of the operation needs to be casted back to a stringstream
static_cast<ostringstream*>
Finally, we get the contents of the resulting stream as a string ->str() and we assign that
value to the string string String =
Custom formatting
Stringstreams allow manipulators and locales to customize the result of these operations
so you can easily change the format of the resulting string
38
2
3 #include <iomanip>
4 #include <locale>
5 #include <sstream>
6 #include <string> // this should be already included in <sstream>
7
8 // Defining own numeric facet:
9
10 class WithComma: public numpunct<char> // class for decimal numbers using comma
11 instead of point
12 {
13 protected:
14 char do_decimal_point() const { return ','; } // change the decimal separator
15 };
16
17
// Conversion code:
18
19
double Number = 0.12; // Number to convert to string
20
21 ostringstream Convert;
22
23 locale MyLocale( locale(), new WithComma);// Crate customized locale
24
Convert.imbue(MyLocale); // Imbue the custom locale to the stringstream
25
26
Convert << fixed << setprecision(3) << Number; // Use some manipulators
27
28 string Result = Convert.str(); // Give the result to the string
29
30 // Result is now equal to "0,120"
39
31
32
33
String to Number
For this ( as you need to read input from the stream ) an istringstream will be used
While a number can always be converted in a string, a string must be valid to be
converted to a number ( eg: An attempt of converting "hello" to an integer would
certainly fail ) so on this conversion, some checking must be done
4
istringstream convert(Text); // stringstream used for the conversion constructed with
5
the contents of 'Text'
6
// ie: the stream will start containing the characters of 'Text'
7
8 if ( !(convert >> Result) ) //give the value to 'Result' using the characters in the stream
9 Result = 0; //if that fails set 'Result' to 0
10
11 //'Result' now equal to 456
40
This conversion is even easier to reduce to a single line:
1 string Text = "456";
2 int Number;
3 if ( ! (istringstream(Text) >> Number) ) Number = 0;
In the above code an object of istringstream gets constructed from
'Text' istringstream(Text) and its contents get read into the numeric variable >> Number.
A generic stringstream ( which could be used both for input and for output ) can be
useful in some more complex situations and in almost any situation you need to perform
operations not provided by string
Here are listed some functions to perform these conversion using stringstreams:
41
5 ss << Number;
6 return ss.str();
7 }
Usage: NumberToString ( Number );
Notice: In the code examples std:: was omitted to make the code simpler
Using the last functions, there is no way of detecting whether the conversion
succeded or failed
Using stringstreams is the standard C++ way of doing these conversions but they usually
need a few lines of code Among the Boost libraries there is lexical_cast which allows to
perform the stringstream conversions through simple function call To make this library
working, just include the header, it doesn't need to be linked
1 // Boost header needed:
2 #include <boost/lexical_cast.hpp>
3
42
4 // Number to string conversion:
5 Text = boost::lexical_cast<string>(Number);
6
7 // String to number conversion:
8 Number = boost::lexical_cast<Type>(Text);
C - stdio
Number to String
In C there is no stream library, but the function sprintf can be used for conversion
It works in a similar way to printf but it will put the characters in a C string ( a character
array ) instead of stdout
43
Using this is not as easy as with streams as the format string changes depending on the
type of the number which needs to be converted
Example:
1 int Number = 123; // number to convert
2
3 char Result[16]; // string which will contain the number
4
sprintf ( Result, "%d", Number ); // %d makes the result be a decimal integer
5
String to Number
As printf, also scanf has a related function which can read from a character array, sscanf
1 char Text[] = "456"; // string to be converted
2
3 int Result; // number which will contain the result
4
sscanf ( Text, "%d", &Result );
5
If sscanf fails ( ie: the string is not a number ), the value of the variable passed remains
unchanged, in that case the function should return zero as no argument were read
successfully, if the string passed is so bad that nothing can be read from it, it would
return EOF:
1 char Text[] = "456"; // string to be converted
2
3 int Result; // number which will contain the result
4
int Succeeded = sscanf ( Text, "%d", &Result );
5
44
6 if ( !Succeeded || Succeeded == EOF ) // check if something went wrong during the
7 conversion
8 Result = 0;
C – stdlib
The stdlib header contains some functions to convert text and numbers
Notice that some of these functions are not standard!
These functions are:
• itoa
• atoi
• atol
• atof
• strtol
• strtoul
• strtod
45
1 /* itoa: convert n to characters in s */
2 void itoa(int n, char s[])
3 {
4 int i, sign;
5
6 if ((sign = n) < 0) /* record sign */
8 i = 0;
12 if (sign < 0)
13 s[i++] = '-';
14 s[i] = '\0';
15 reverse(s);
16 }
8 c = s[i];
9 s[i] = s[j];
10 s[j] = c;
11 }
46
12 }
reverse uses the function strlen from the header cstring ( string.h in C )
This is easy to implement, here is an example:
1 /* strlen: return length of s */
2 int strlen(char s[])
3{
4 int i = 0;
5 while (s[i] != '\0')
6 ++i;
7 return i;
8}
As you can see, is possible to create a ( bad ) conversion function with just some basic C
The same applies to the opposite conversion:
1 /* atoi: convert s to integer */
2 int atoi(char s[])
3{
4 int i, n;
5 n = 0;
6 for (i = 0; s[i] >= '0' && s[i] <= '9'; ++i)
7 n = 10 * n + (s[i] - '0');
8 return n;
9}
Of course these functions are bad for many reasons and should not be used in actual code
They just show the idea behind the conversion between an integer value and a character
sequence
47
How To: Ask Questions The Smart Way
Introduction
In the world of programming, the kind of answers you get to your technical questions
depends as much on the way you ask the questions as on the difficulty of developing the
answer. The first thing to understand is that programmers actually like hard problems
and good, thought-provoking questions about them. If we didn't, we wouldn't be here
Programmers have a reputation for meeting simple questions with what looks like
hostility or arrogance. It sometimes looks like we're reflexively rude to newbies and the
ignorant. But this isn't really true.
1. Try to find an answer by searching the archives of the forum you plan to post to.
2. Try to find an answer by searching the Web.
3. Try to find an answer by reading the manual.
4. Try to find an answer by reading a FAQ.
5. Try to find an answer by inspection or experimentation.
6. Try to find an answer by asking a skilled friend.
48
Prepare your question. Think it through. Hasty-sounding questions get hasty answers or
none at all.
49
Be precise and informative about your problem
Do the best you can to anticipate the questions a respondent will ask, and answer them in
advance in your request for help.
You need to be precise and informative. This end is not served by simply dumping huge
volumes of code or data into a help request. If you have a large, complicated test case
that is breaking a program, try to trim it and make it as small as possible. This is useful
for at least three reasons. One: being seen to invest effort in simplifying the question
makes it more likely you'll get an answer, Two: simplifying the question makes it more
likely you'll get a useful answer. Three: In the process of refining your bug report, you
may develop a fix or workaround yourself.
It's not useful to tell programmers what you think is causing your problem. So, make
sure you're telling them the raw symptoms of what goes wrong, rather than your
50
interpretations and theories. Let them do the interpretation and diagnosis. If you feel it's
important to state your guess, clearly label it as such and describe why that answer isn't
working for you.
If you are trying to find out how to do something, begin by describing the goal. Only
then describe the particular step towards it that you are blocked on. Often, people who
need technical help have a high-level goal in mind and get stuck on what they think is
one particular path towards the goal. They come for help with the step, but don't realize
that the path is wrong. It can take substantial effort to get past this.
Open-ended questions tend to be perceived as open-ended time sinks. Those people most
likely to be able to give you a useful answer are also the busiest people (if only because
they take on the most work themselves). People like that are allergic to open-ended time
sinks, thus they tend to be allergic to open-ended questions.
You are more likely to get a useful response if you are explicit about what you want
respondents to do (provide pointers, send code,..). This will focus their effort and
implicitly put an upper bound on the time and energy a respondent must allocate to
helping you.
51
response. If you simply want a code review, say as much up front, and be sure to
mention what areas you think might particularly need review and why.
Besides being courteous and informative, this sort of followup will help others searching
the archive of the mailing-list/newsgroup/forum to know exactly which solution helped
you and thus may also help them.
Last, and not least, this sort of followup helps everybody who assisted feel a satisfying
sense of closure about the problem. Problem narratives that trail off into unresolved
nothingness are frustrating things; programmers itch to see them resolved. The goodwill
that scratching that itch earns you will be very, very helpful to you next time you need to
pose a question.
52
If you don't understand the answer, do not immediately bounce back a demand for
clarification. Use the same tools that you used to try and answer your original question
(manuals, FAQs, the Web, skilled friends) to understand the answer. Then, if you still
need to ask for clarification, exhibit what you have learned.
If you can't get an answer, please don't take it personally that we don't feel we can help
you. Sometimes the members of the asked group may simply not know the answer. No
response is not the same as being ignored, though admittedly it's hard to spot the
difference from outside.
In general, simply re-posting your question is a bad idea. This will be seen as pointlessly
annoying. Have patience: the person with your answer may be in a different time-zone
and asleep. Or it may be that your question wasn't well-formed to begin with.
53
Ask probing questions to elicit more details. If you're good at this, the querent will
learn something - and so might you. Try to turn the bad question into a good one;
remember we were all newbies once.
While muttering RTFM is sometimes justified when replying to someone who is just a
lazy slob, a pointer to documentation (even if it's just a suggestion to google for a key
phrase) is better.
If you're going to answer the question at all, give good value. Don't suggest kludgy
workarounds when somebody is using the wrong tool or approach. Suggest good tools.
Reframe the question.
54