C++ 11:
using range-based for loop:
#include<iostream>
#include "animals.hpp"
using namespace std;
int main(int argc, char ** argv){
Dog a ("arnie");
Dog b ("barky");
Dog c ("not a cat");
for(const Dog & d: {a, b, c}){
/* for(Dog & d : {a, b, c}) is wrong
* you cannot bind a non-const reference to a const-object,
* as that would drop (discard in other compiler's errors),
* disregard or ignore the const qualifier.
*/
d.speak();
}
for(Dog * d: {&a, &b, &c}){
d->speak();
}
return 0;
}
arnie the dog says woof
barky the dog says woof
not a cat the dog says woof
arnie the dog says woof
barky the dog says woof
not a cat the dog says woof
ambiguous null pointer constants:
// nullptr.cpp by Bill Weinman <http://bw.org/>
#include <iostream>
using namespace std;
#ifndef NULL
#define NULL 0 /* standard C++ definition */
#endif
void f( int i ) {
printf("the int is %d\n", i);
}
void f( char * s ) {
printf("the pointer is %p\n", s);
}
int main( int argc, char ** argv ) {
f(NULL); //which function it will call is uncertain
return 0;
}
new in C++11:
#include <iostream>
using namespace std;
#ifndef NULL
#define NULL 0 /* standard C++ definition */
#endif
void f( int i ) {
printf("the int is %d\n", i);
}
void f( char * s ) {
printf("the pointer is %p\n", s);
}
int main( int argc, char ** argv ) {
f(nullptr);
return 0;
}
the pointer is 00000000
type inference:
各种编译器的输出不一样。对于大部分编译器,包括g和clang,输出的都是编译器内部的类型而不是可读的类型。比如上面的例子在g++5.3.0编译后的输出为NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
#include<iostream>
#include<typeinfo>
using namespace std;
template<typename lhsT, typename rhsT>
auto tf(lhsT lhs, rhsT rhs) -> decltype(lhs + rhs){
return lhs + rhs;
}
int main(int argc, char** argv){
int i = 47;
const char * cstr = "this is a c-string";
string sclass = string("this is a string class string");
auto x = string("this si a string class string");
decltype(x) y;
cout << "type of i is " << typeid(i).name() << endl;
cout << "type of cstr is " << typeid(cstr).name() << endl;
cout << "type of sclass is " << typeid(sclass).name() << endl;
cout << "type of x is " << typeid(x).name() << endl;
cout << "type of y is " << typeid(y).name() << endl;
auto z = tf(sclass, cstr);
cout << "type of z is " << typeid(z).name() << endl;
return 0;
}
type of i is i
type of cstr is PKc
type of sclass is NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
type of x is NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
type of y is NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
type of z is NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
lambda function:
[& lastc ] the capture, use variables outside the scope of lambda function
Capture | Meaning |
[ ] | no external variables may be accessed |
[x, &y] | x is captured by value, y is capture by reference |
[&] | any external variable is implicitly captured by reference, if used |
[=] | any external variable is implicitly captured by value, if used |
[&, x] | x is captured by value, any other variables will be captured by reference |
[=, &z] | z is captured by reference, any other variables will be captured by value |
(char c) argument list
-> char return type
{ } function body
#include<iostream>
#include<algorithm>
#include<locale>
using namespace std;
class fupper{
char lastc;
public:
fupper(): lastc(0) {}
char operator() (char c);
};
char fupper::operator ()(char c){
if(lastc==0 || lastc==' '){
lastc = c;
return toupper(c);
}else{
lastc = c;
return tolower(c);
}
}
int main(int argc, char ** argv){
string s = "big light in the sky slated to appear in east";
//transform(s.begin(), s.end(), s.begin(), fupper());
char lastc = 0;
transform(s.begin(), s.end(), s.begin(),
[&lastc] (char c) -> char{
if(lastc==0 || lastc==' '){
lastc = c;
return toupper(c);
}else{
lastc = c;
return tolower(c);
}
}
);
cout << s << endl;
return 0;
}
Big Light In The Sky Slated To Appear In East
standard template library
#include<iostream>
#include<vector>
#include<algorithm>
#include<locale>
using namespace std;
class strhas{
char needle;
strhas() {}
public:
strhas(char c): needle(c){}
bool operator() (string & s);
};
bool strhas::operator() (string & s){
return (s.find_first_of(needle) != s.npos);
}
string uppercase(string & s){
string out;
for(char c: s){
out += toupper(c);
}
return out;
}
int main(int argc, char ** argv){
vector<string> vs = {"one","two","three","four","five","six","seven","eight","nine","ten"};
vector<int> vi = {1,2,3,4,5,6,7,8,9,10};
vector<string>::iterator vsit;
vector<int>::iterator viit;
cout << "push two extra sevens onto vs" << endl;
vs.push_back("seven");
vs.push_back("seven");
cout << "count vs \"seven\": " << count(vs.begin(), vs.end(), "seven") << endl;
cout << "pop those extra sevens" << endl;
vs.pop_back();
vs.pop_back();
cout << "find 7 in vi: ";
viit = find(vi.begin(), vi.end(), 7);
if(viit != vi.end()){
cout << "found: " << *viit << endl;
}else{
cout << "not found" << endl;
}
string p = "radar";
if(equal(p.begin(), p.begin()+(p.size()/2), p.rbegin())){
cout << p << " is";
} else{
cout << p << " is not";
}
cout << " a palindrome" << endl;
string s1 = "big light in sky slated to appear in east";
string match = "slated";
string::iterator search_it = search(s1.begin(), s1.end(), match.begin(), match.end());
cout << "string is \"" << s1 << "\", search term is \"" << match << "\"" << endl;
cout << "search: search term found at position " << (search_it - s1.begin()) << endl;
cout << "vs is: ";
for(string s: vs){
cout << s << " ";
}
cout << endl;
cout << "count_if vs has 's' (functor): " << count_if(vs.begin(), vs.end(), strhas('s')) << endl;
cout << "count_if vs has 's' (lambda): " << count_if(vs.begin(), vs.end(),
[] (string & s) -> bool{
return (s.find_first_of('s') != s.npos);
}
) << endl;
cout << "for_each uppercase: ";
for_each(vs.begin(), vs.end(), [] (string & s) -> void {
cout << uppercase(s) << " ";
});
cout << endl;
cout << "transform" << endl;
cout << "vi before transformation: ";
for(int i: vi) cout << i <<" ";
cout << endl;
vector<int> vi2;
vi2.resize(vi.size());
transform(vi.begin(), vi.end(), vi2.begin(),
[] (int i) -> int {return ++i;});
cout << "vi2 after transformation: ";
for(int i: vi2) cout << i << " ";
cout << endl;
transform(vi.begin(), vi.end(), vi2.begin(), vi2.begin(),
[] (int i, int j) -> int {return i+j;});
cout << "vi2 after second transformation: ";
for(int i: vi2) cout << i << " ";
cout << endl;
cout << "string before initial cap transformation: " << s1 << endl;
char lastc = 0;
transform(s1.begin(), s1.end(), s1.begin(), [&lastc] (char c) -> char {
if(lastc == 0 || lastc == ' ') {lastc = c; return toupper(c);}
else {lastc = c; return tolower(c);}
});
cout << "string after initial cap transformation: " << s1 << endl;
return 0;
}
push two extra sevens onto vs
count vs "seven": 3
pop those extra sevens
find 7 in vi: found: 7
radar is a palindrome
string is "big light in sky slated to appear in east", search term is "slated"
search: search term found at position 17
vs is: one two three four five six seven eight nine ten
count_if vs has 's' (functor): 2
count_if vs has 's' (lambda): 2
for_each uppercase: ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE TEN
transform
vi before transformation: 1 2 3 4 5 6 7 8 9 10
vi2 after transformation: 2 3 4 5 6 7 8 9 10 11
vi2 after second transformation: 3 5 7 9 11 13 15 17 19 21
string before initial cap transformation: big light in sky slated to appear in east
string after initial cap transformation: Big Light In Sky Slated To Appear In East
formatted io:
(1) | istream& getline (istream& is, string& str, char delim); istream& getline (istream&& is, string& str, char delim); |
---|---|
(2) | istream& getline (istream& is, string& str); istream& getline (istream&& is, string& str); |
Get line from stream into string
Extracts characters from
is and stores them into
str until the delimitation character
delim is found (or the newline character,
'\n', for
(2)).
The extraction also stops if the end of file is reached in is or if some other error occurs during the input operation.
If the delimiter is found, it is extracted and discarded (i.e. it is not stored and the next input operation will begin after it).
#include<iostream>
#include<iomanip>
using namespace std;
int main(int argc, char ** argv){
cout << "Hello, World!\n";
cout << "Promtp: ";
string istr = "";
cin >> istr;
cout << "Input: " << istr << endl;
int i1 = 42, i2 = 127, i3 = 5555;
cout << "default: " << i1 << " " << i2 << " " << i3 << endl;
cout << "hex: " << hex << i1 << " " << i2 << " " << i3 << endl;
cout << "hex with showbase: " << showbase << hex << i1 << " " << i2 << " " << i3 << endl;
cout << "octal with showbase: " << showbase << oct << i1 << " " << i2 << " " << i3 << endl;
cout << "default: " << noshowbase << dec << i1 << " " << i2 << " " << i3 << endl;
double d1 = 3.1415926534, d2 = 1234.5, d3 = 4.2e-10;
cout << "default: " << d1 << " " << d2 << " " << d3 << endl;
cout << "fixed: " << fixed << d1 << " " << d2 << " " << d3 << endl;
cout << "scientific: " << scientific << d1 << " " << d2 << " " << d3 << endl;
cout << "fixed (3): " << setprecision(3) << fixed
<< d1 << " " << d2 << " " << d3 << endl;
cout << "scientific (7): " << setprecision(7) << scientific
<< d1 << " " << d2 << " " << d3 << endl;
cout.unsetf(ios_base:: floatfield);
cout << "default: " << d1 << " " << d2 << " " << d3 << endl;
string s1 = "This is a string.";
string s2 = "This is a much longger string.";
string s3 = "Today's news: Big Light in Sky Slated to Appear in East.";
cout << s1 << endl;
cout << s2 << endl;
cout << s3 << endl;
cout << setw(64) << right << s1 << endl;
cout << setw(64) << right << s2 << endl;
cout << setw(64) << right << s3 << endl;
cout << setfill('-') << setw(64) << right << s1 << endl;
cout << setfill(' ') << setw(64) << right << s1 << endl;
cout << left << s1 << endl;
return 0;
}
Hello, World!
Promtp: one two three
Input: one
default: 42 127 5555
hex: 2a 7f 15b3
hex with showbase: 0x2a 0x7f 0x15b3
octal with showbase: 052 0177 012663
default: 42 127 5555
default: 3.14159 1234.5 4.2e-010
fixed: 3.141593 1234.500000 0.000000
scientific: 3.141593e+000 1.234500e+003 4.200000e-010
fixed (3): 3.142 1234.500 0.000
scientific (7): 3.1415927e+000 1.2345000e+003 4.2000000e-010
default: 3.141593 1234.5 4.2e-010
This is a string.
This is a much longger string.
Today's news: Big Light in Sky Slated to Appear in East.
This is a string.
This is a much longger string.
Today's news: Big Light in Sky Slated to Appear in East.
-----------------------------------------------This is a string.
This is a string.
This is a string.
file io:
#include<iostream>
#include<string>
#include<fstream>
using namespace std;
string lineno(){
static int lineint = 0;
static char linestr[3];
if(lineint >= 99) lineint = 0;
snprintf(linestr, 3, "%02d", ++lineint);
return string(linestr);
}
int main(int argc, char ** argv){
const char * filename = "test.txt";
string buffer;
cout << "write the file:" << endl;
ofstream ofile(filename);
ofile << lineno() << " " << "This is the test file." << endl;
ofile << lineno() << " " << "This is the test file." << endl;
ofile << lineno() << " " << "This is the test file." << endl;
ofile.close();
cout << "read the file:" << endl;
ifstream ifile(filename);
while(ifile.good()){
getline(ifile, buffer);
cout << buffer << endl;
}
//cout << endl;
ifile.close();
cout << "open file for append:" << endl;
fstream afile(filename, fstream::in | fstream::out | fstream::app);
if(!afile.good()){
cout << "failed to open" << endl;
exit(0);
}
cout << "current contents:" << endl;
//seek to beginning of file
afile.seekg(0, fstream::beg);
while(afile.good()){
getline(afile, buffer);
cout << buffer << endl;
}
//cout << endl;
afile.clear(); //clear error flags after reading to eof
cout << "append lines:" << endl;
afile << lineno() << " This is the test file" << endl;
afile << lineno() << " This is the test file" << endl;
afile << lineno() << " This is the test file" << endl;
cout << "content after append:" << endl;
afile.seekg(0, fstream::beg);
while(afile.good()){
getline(afile, buffer);
cout << buffer << endl;
}
//cout << endl;
afile.close();
cout << "delete file." << endl;
remove(filename);
return 0;
}
write the file:
read the file:
01 This is the test file.
02 This is the test file.
03 This is the test file.
open file for append:
current contents:
01 This is the test file.
02 This is the test file.
03 This is the test file.
append lines:
content after append:
01 This is the test file.
02 This is the test file.
03 This is the test file.
04 This is the test file
05 This is the test file
06 This is the test file
delete file.
handling exceptions:
#include <iostream>
#include <exception>
using namespace std;
class myexception : public exception {
string s;
public:
myexception(const char * message): s(message) {}
const char * what() const throw();//must be the same, otherwise it is not overloaded
};
const char * myexception::what() const throw() {
return s.c_str();
}
//make program scalable: a limited number of exception message
const myexception e_ouch("ouch!");
const myexception e_bad("bad code!");
const myexception e_worse("don't do that!");
void broken() {
cout << "this is a broken function" << endl;
throw e_worse;
}
int main( int argc, char ** argv ) {
try{
cout << "let's have an emergency!" << endl;
broken();
}catch(exception & e){
cout << e.what() << endl;
}
cout << "this is still running" << endl;
return 0;
}
let's have an emergency!
this is a broken function
don't do that!
this is still running