您的位置:首页 > 编程语言 > C语言/C++

Cpp复习(二)

2018-02-14 03:48 288 查看
__________________________________________________________________________________________________________________________________________

standard c library: file IO, strings, memory allocation, date and time, error handling, other utilities, consists of two parts: header files and runtime support.

c: #include<stdio.h>,  c++: #include<cstdio> symbol are in std namespace

runtime support is provided by a compiled runtime library(libc, glibc) that is linked to the program as part of the build process.

FILE * fopen(const char * filename, const char * mode)

char * fgets(char * buf, int count, FILE * stream)

int fputs(char * str, FILE * stream)

size_t fread(void * buffer, size_t size, size_t count, FILE * stream) //returns the number of buffers read successfully

int fwrite(void * buffer, size_t size, size_t count, FILE * stream) //non negative number for success, EOF for end of file(failure)

mode stringmeaningif file existsif file does not exist
ropen file for readingread from startfailure
wcreate a file for writingdestroy contentscreate new file
aappend to a filewrite from endcreate new file
r+open file for read /writeread from startfailure
w+ create file for read / writedestroy contentscreate new file
a+open file for read / writewrite from endcreate new file
bbinary mode  
fgets and fputs:

#include<stdio.h>

int main(int argc, char ** argv){
const char * fn = "test.txt";
const char * str = "This is a literal C-string\n";
const static int maxString = 1024;

printf("writing file\n");
FILE * fw = fopen(fn, "w");
for(int i=0; i < 5; i++){
fputs(str, fw);
/*fputs does not write additional characters,
* while puts appends a newline character at the end automatically.
* The function begins copying from the address specified (str) until it reaches the terminating null character ('\0').
* This terminating null-character is not copied to the stream.
*On success, a non-negative value is returned. On error, the function returns EOF and sets the error indicator (ferror).
*/
}
fclose(fw);
printf("done.\n");

printf("reading file\n");
char * rc;
FILE * fr = fopen(fn, "r");
char buf[maxString];
while((rc = fgets(buf, maxString, fr))){
printf(buf);
/* Reads characters from stream and stores them as a C string into str
* until (num-1) characters have been read or either a newline
* or the end-of-file is reached, whichever happens first.
* A newline character makes fgets stop reading,
* but it is considered a VALID character by the function
* and included in the string copied to str.
* A terminating null character is automatically appended after the characters copied to str.
* On success, the function returns str.
* If the end-of-file is encountered while attempting to read a character,
* the eof indicator is set (feof).
* If this happens before any characters could be read,
* the pointer returned is a null pointer (and the contents of str remain unchanged).
*/
}
fclose(fr);
printf("done.\n");
}

writing file...

Done.

reading file...

This is a literal C-string.

This is a literal C-string.

This is a literal C-string.

This is a literal C-string.

This is a literal C-string.
Done.

#include<stdio.h>
#include<string.h>
#include<stdint.h>

//const int slen = 128;
enum{ slen = 128 }; //define a constant
struct s1{
uint8_t a; //a byte that is used as a integer, not a char(unsigned char)
uint8_t b;
char s[slen];
};
int main(int argc, char ** argv){
const char * fn = "test.txt";
const char * str = "This is a literal C-string.\n";

printf("writing file...\n");
FILE * fw = fopen(fn, "wb");
struct s1 buf1[5];
for(int i=0; i < 5; i++){
buf1[i].a = i;
buf1[i].b = strlen(str);
strncpy(buf1[i].s, str, slen);
/*
* char * strncpy(char * dest, const char * src, size_t num)
* Copies the first num characters of source to destination.
* If the end of the source C string (which is signaled by a null-character)
* is found before num characters have been copied,(so length of the content to be copied <= num-1)
* *destination is padded with zeros until a total of num characters have been written to it.
* No null-character is implicitly appended at the end of destination
* if source is longer than num.
*/
}
fwrite(buf1, sizeof(struct s1), 5, fw);
fclose(fw);
printf("done.\n");

printf("reading file...\n");
FILE * fr = fopen(fn, "rb");
struct s1 buf2;
int rc;
while((rc = fread(&buf2, sizeof(struct s1), 1, fr))){
printf("the number of the buffers read:%d\n", rc);
printf("a: %d, b: %d, s: %s", buf2.a, buf2.b, buf2.s);
}
fclose(fr);
printf("done.\n");
return 0;
}


writing file...

done.

reading file...

the number of the buffers read:1

a: 0, b: 28, s: This is a literal C-string.

the number of the buffers read:1

a: 1, b: 28, s: This is a literal C-string.

the number of the buffers read:1

a: 2, b: 28, s: This is a literal C-string.

the number of the buffers read:1

a: 3, b: 28, s: This is a literal C-string.

the number of the buffers read:1

a: 4, b: 28, s: This is a literal C-string.

done.

int rename(const char * oldname, const char * newname)

int remove(const char * filename)

unformated io:

printf("Hello world!\n");//formatted
puts("Hello world!");
fputs("Hello world!\n", stdout);  fgets(buf, maxlen, fr);

formatted io:
%d int, %ld long int, %s char *, %c char, %p pointer, %f float point number; stdout, stdin, stderr

int printf( const char * format, ...)

int fprintf(FILE * fn, const char * format, ...)

//the above two funcs:On success, the total number of characters written is returned; otherwise, a negative number is returned

int sprintf(char * buf, const char * format, ...)

//On success, the total number of characters written is returned. This count does NOT include the additional null-character automatically appended at the end of the string.On
failure, a negative number is returned.

int snprintf(char * buf, size_t bufsize, const char * format, ...)

//If the resulting string would be longer than n-1 characters,
the remaining characters are discarded and not stored, but counted for the value returned by the function. A terminating null character is automatically appended after the content written.

//The number of characters that would have been written if n had
been sufficiently large, NOT counting the terminating null character.If an encoding error occurs, a negative number is returned.

//Notice that only when this returned value is non-negative and less than n(len <= n-1), the string has been completely written.

building string functions

1,
4000
char *strncpy(char * dest, const char * src, size_t num)  

//Only when the length of content to be copied is <= num-1 can a terminating null be added. (num chars in total)

2,char * strncat(char * dest, const char * src, size_t num) 

//Appends the first num characters of source to destination, plus a terminating null-character.

//e.g. strncat(str1, str2, maxBuf - strlen(str1) -1)

3.int strcmp(const char* str1, const char * str2)

4const char* strchr(const char * str, int character)

//Returns a pointer to the first occurrence of character in
the C string str.If the character is not found, the function returns a null pointer.

//The terminating null-character is considered part of the C string. Therefore, it can also be located in order to retrieve a pointer to the end of a string

5/const char * strstr(const char * str1, const char * str2)

//Returns a pointer to the first occurrence of str2 in str1,
or a null pointer if str2 is not part of str1. The
matching process does not include the terminating null-characters, but it stops there.

6.size_t strlen(char * str)

memory allocation

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main(int argc, char ** argv){
const char * src = "This is a string";
const static int strSize = 1024;
char * string = NULL;

string = (char *)calloc(strSize, sizeof(char));
//string = malloc(strSize * sizeof(char));
//the difference is that calloc actively writes zero to the memory
if(!string){
fputs("cannot allocate memory.\n", stderr);
return 1;
}
strncpy(string, src, strSize);
puts(string);

free(string);
string = NULL;
return 0;
}

handling system errors

1,void perror (const char * str)

//print out str to standard error followed by error string translated from the error mode

#include<stdio.h>
#include<errno.h>

int main(int argc, char ** argv){
printf("errno is: %d\n", errno);
printf("Erasing file foo.bar\n");
remove("foo.bar");
printf("errno is: %d\n", errno);
perror("Couldn't erase file");
return 0;
}

errno is: 0

Erasing file foo.bar

errno is: 2

Couldn't erase file: No such file or directory

2,char * strerror(int errnum)

#include<stdio.h>
#include<errno.h>
#include<string.h>

int main(int argc, char ** argv){
printf("errno is: %d\n", errno);
printf("Erasing file foo.bar\n");
remove("foo.bar");
printf("errno is: %d\n", errno);
printf("the error message is %s\n", strerror(errno));
return 0;
}

errno is: 0

Erasing file foo.bar

errno is: 2

the error message is No such file or directory

date and time functions:

time_t time(time_t * time);


time_t is a 32bit signed integer, giving the number of seconds since midnight January 1970 GMT

struct tm * gmtime (const time_t * timer);


Convert time_t to tm as UTC time
Uses the value pointed by timer to fill a tm structure with the values that represent the corresponding time, expressed as a UTC time (i.e., the time
at the GMT timezone).

struct tm * localtime (const time_t * timer);


Convert time_t to tm as local time
Uses the value pointed by timer to fill a tm structure with the values that represent the corresponding time, expressed for the local timezone.

size_t strftime (char* ptr, size_t maxsize, const char* format,
const struct tm* timeptr );


Format time as string
Copies into ptr the content of format, expanding its format specifiers into the corresponding values that represent the time described in timeptr, with a limit of maxsize characters.


Return Value

If the length of the resulting C string, including the terminating null-character, doesn't exceed maxsize,
the function returns the total number of characters copied to ptr (not including the terminating null-character).
Otherwise, it returns zero, and the contents of the array pointed by ptr are
indeterminate.

#include<stdio.h>
#include<time.h>

int main(){
const static int bufSize = 128;
time_t t = time(NULL);
struct tm gmt = *gmtime(&t);
struct tm localt = *localtime(&t);
printf("direct from struct tm:\n");
printf("universal time is now %04d-%02d-%02d %02d:%02d:%02d\n",
gmt.tm_year + 1900, gmt.tm_mon, gmt.tm_mday, gmt.tm_hour, gmt.tm_min, gmt.tm_sec);

char buf[bufSize];
size_t len = strftime(buf, bufSize, "%Y-%m-%d %H:%M:%S", &gmt);
printf("from strftime (gmt):\n");
printf("universal time is now %s (%u characters)\n", buf, len);

len = strftime(buf, bufSize,"%Y-%m-%d %H:%M:%S", &localt);
printf("from strftime (localt):\n");
printf("local time is now %s (%u characters)\n", buf, len);

return 0;
}

direct from struct tm:

universal time is now 2018-01-12 20:48:56

from strftime (gmt):

universal time is now 2018-02-12 20:48:56 (19 characters)

from strftime (localt):

local time is now 2018-02-13 04:48:56 (19 characters)

getting file info:

struct stat: 

fieldinterpretation
st_modesize of file in bytes
st_inofile ino number
st_modefile mode
st_nlinknumber of hard links
st_uidowner user id
st_gidowner group id
st_ctimefile creation time
st_mtimefile modification time
st_atimefile access time
int stat( char* filename, struct stat * info);

//0 for success, non-zero for failure. 

struct stat fstat;

stat("stat.c", &fstat); // info stored in fstat

__________________________________________________________________________________________________________________________________________

STL standard template library

vector, list, set, map, queue and stack, string, io streams, algorithms

vector:

#include<iostream>
#include<vector>
using namespace std;

int main(int argc, char ** argv){
cout << "vector from initializer list (C++11):" << endl;
vector<int> vi1 = {1,2,3,4,5,6,7,8,9,10};
cout << "size: " << vi1.size() << endl;
cout << "front: " << vi1.front() << endl;
cout << "back: " << vi1.back() << endl;

cout <<"insert 42 at begin + 5:" << endl;
vi1.insert(vi1.begin()+5, 42);
cout <<"size: " << vi1.size() << endl;
cout <<"vi1[5]: " << vi1[5] << endl;
cout << "erase at begin + 5:" << endl;
vi1.erase(vi1.begin()+5);
cout << "size: " << vi1.size() << endl;
cout << "vi1[5]: " << vi1[5] << endl;

cout << "push_back 47:" << endl;
vi1.push_back(47);
cout << "size: " << vi1.size() << endl;
cout << "vi1.back() " << vi1.back() << endl;

cout << "range-based iterator(C++11):" << endl;
for(int & v: vi1){
cout << v << " ";
}
cout << endl << endl;

cout << "vector from C-array:" << endl;
const static int size = 10;
int ia[size] = {1,2,3,4,5,6,7,8,9,10};
vector<int> vi2(ia, ia+size);
cout << "plain old for loop (i:v)" << endl;
for(int i = 0; i < size; i++) {
cout << i << ":" << vi2[i] << " ";
}
cout << endl << endl;
cout << "iterator loop" << endl;
for(vector<int>::iterator it=vi2.begin(); it!=vi2.end(); ++it){
cout << (it-vi2.begin())<< ":" << *it << " ";
}
cout << endl << endl;

cout << "vector of strings, from argc/argv list: " << endl;
vector<string> args(argv, argv+argc);
for(string & v: args){
cout << v << endl;
}
}

vector from initializer list (C++11):

size: 10

front: 1

back: 10

insert 42 at begin + 5:

size: 11

vi1[5]: 42

erase at begin + 5:

size: 10

vi1[5]: 6

push_back 47:

size: 11

vi1.back() 47

range-based iterator(C++11):

1 2 3 4 5 6 7 8 9 10 47 

vector from C-array:

0:1 1:2 2:3 3:4 4:5 5:6 6:7 7:8 8:9 9:10 

vector of strings, from argc/argv list: 

F:\workspace\CppWorking\Debug\CppWorking.exe

one

two

three

pair and tuple:

#include<iostream>
#include<tuple>
#include<utility>
using namespace std;

int main(int argc, char ** argv){
pair<int, string> p(42, "forty-two");
cout << p.first << " " << p.second << endl;

p = make_pair<int, string>(112, "one-one-two");
cout << p.first << " " << p.second << endl;

tuple<string, string, int> t1("one", "two", 3);
cout << get<0>(t1) << " " << get<1>(t1) << " " << get<2>(t1) << endl;

string a, b;
int c;
tie(a, b, c) = t1;
cout << a << " " << b << " " << c << endl;

tuple<int, string, string> t2;
tie(get<2>(t2), get<1>(t2), get<0>(t2)) = t1;
cout << get<0>(t2) << " " << get<1>(t2) << " " << get<2>(t2) << endl;
return 0;
}

42 forty-two

112 one-one-two

one two 3

one two 3

3 two one

types of iterators
https://www.geeksforgeeks.org/forward-iterators-in-cpp/ 
1, input iterator: 

https://www.geeksforgeeks.org/input-iterators-in-cpp/

Input iterators can be used only with single-pass
algorithms, i.e., algorithms in which we can go to all the locations in the range at most once, like when we have to search or find any element
in the range, we go through the locations at most once.

std:copy Now, as far as accessing elements are concerned, input iterators are fine, but
as soon as we have to assign elements in another container, then we cannot use these input iterators for this purpose.(only accessing, no assigning)

template
OutputIterator copy(InputIterator first, InputIterator last,
OutputIterator result)
{
while (first != last)
*result++ = *first++;
return result;
}

2, output iterator

https://www.geeksforgeeks.org/output-iterators-cpp/
Output iterators are considered to be the exact
opposite of input iterators, as they perform opposite function of input iterators. They can be assigned
values in a sequence, but cannot be used to access values.

Output iterators can be used only with single-pass
algorithms, i.e., algorithms in which we can go to all the locations in the range at most once, such that these locations can be dereferenced
or assigned value only once.

Equality / Inequality Comparison: Unlike input iterators, output
iterators cannot be compared for equality with another iterator.

So, the following two expressions are invalid if A and B are output iterators:
A == B  // Invalid - Checking for equality
A != B  // Invalid - Checking for inequality


3.forward iterator

Forward iterators are considered to be the combination
of input as well as output iterators. It provides support to the functionality of both of them. It permits values to be both accessed and modified.

Usability: Performing operations on a forward iterator that is dereferenceable never makes its iterator value non-dereferenceable, as a result this enables algorithms that use
this category of iterators to use multiple copies of an iterator to pass more than once by the same iterator values. So, it can be used in multi-pass
algorithms.

Equality / Inequality Comparison: A forward iterator can be compared for equality with another iterator. Since, iterators point to some location, so the two iterators will be
equal only when they point to the same position, otherwise not.

So, the following two expressions are valid if A and B are forward iterators:
A == B  // Checking for equality
A != B  // Checking for inequality


std::reverse_copy: As
the name suggests, this algorithm is used to copy a range into another range, but in reverse order. Now, as far as accessing elements and assigning elements are concerned, forward iterators are fine, but
as soon as we have to decrement the iterator, then we cannot use these forward iterators for this purpose.

// Definition of std::reverse_copy()
template OutputIterator reverse_copy(BidirectionalIterator first,
BidirectionalIterator last,
OutputIterator result)
{
while (first != last)
*result++ = *--last;
return result;
}

Relational Operators: Although,
forward iterators can be used with equality operator (==), but it cannnot be used with other relational operators like , =.
If A and B are forward iterators, then

A == B     // Allowed
A <= B     // Not Allowed

3.bidirectional iterators

Bidirectional iterators are iterators that can be used to access the sequence of elements in a range in both directions (towards the end and towards the beginning). They are similar
to forward iterators, except that they can move in the backward direction also, unlike the forward iterators, which can move only in forward direction.

It is to be noted that containers like list, map, multimap, set and multiset support bidirectional iterators. This means that if
we declare normal iterators for them, and then those will be bidirectional iterators, just like in case of vectors and deque they are random-access iterators.

Usability: Since, forward iterators can be used in multi-pass algorithms, i.e., algorithm which involves processing the container several times in various passes, therefore bidirectional
iterators can also be used in multi-pass algorithms.

.

Equality / Inequality Comparison: A Bidirectional iterator can be compared for equality with another iterator. Since, iterators point to some location, so the two iterators will
be equal only when they point to the same position, otherwise not.

So, the following two expressions are valid if A and B are Bidirectional iterators:
A == B  // Checking for equality
A != B  // Checking for inequality


std::random_shuffle: As
we know this algorithm is used to randomly shuffle all the elements present in a container.

// Definition of std::random_shuffle()
template
void random_shuffle(RandomAccessIterator first,
RandomAccessIterator last,
RandomNumberGenerator& gen)
{
iterator_traits::difference_type i, n;
n = (last - first);
for (i=n-1; i>0; --i)
{
swap (first[i],first[gen(i+1)]);
}
}

4, random  access iterator
https://www.geeksforgeeks.org/random-access-iterators-in-cpp/
Random-access iterators are iterators that can be used to access elements at an arbitrary offset position relative
to the element they point to, offering the same functionality as pointers. Random-access iterators are the most complete iterators in terms of functionality. All pointer
types are also valid random-access iterators.It is to be noted that containers like vector,
deque support random-access iterators.
Decrementable: Just
like we can use operator ++() with Random-access iterators for incrementing them, we can also decrement them.

Relational Operators: Although, Bidirectional iterators cannot be used with relational operators like , =,but random-access iterators being higher in hierarchy support all these
relational operators.
If A and B are Random-access iterators, then

A == B     // Allowed
A <= B     // Allowed


Arithmetic Operators: Similar to relational operators, they also can be used with arithmetic operators like +, – and so on. This means that Random-access iterators can move in
both the direction, and that too randomly.
If A and B are Random-access iterators, then

A + 1     // Allowed
B - 2     // Allowed


// C++ program to demonstrate Random-access iterator
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int>v1 = {1, 2, 3, 4, 5};

// Declaring first iterator
vector<int>::iterator i1;

// Declaring second iterator
vector<int>::iterator i2;

// i1 points to the beginning of the list
i1 = v1.begin();

// i2 points to the end of the list
i2 = v1.end();

// Applying relational operator to them
if ( i1 < i2)
{
cout << "Yes";
}

// Applying arithmetic operator to them
int count = i2 - i1;

cout << "\ncount = " << count;
return 0;
}

Use of offset dereference operator ([ ]): Random-access
iterators support offset dereference operator ([ ]), which is used for random-access.
If A is a Random-access iterator, then
A[3]    // Allowed

// C++ program to demonstrate Random-access iterator
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int>v1 = {1, 2, 3, 4, 5};
int i;

// Accessing elements using offset dereference
// operator [ ]
for(i=0;i<5;++i)
{
cout << v1[i] << " ";
}
return 0;
}


————————————————

writing iterator

#include<iostream>
#include<vector>
using namespace std;

int main(int argc, char ** argv){
vector<int> vi1 = {1,2,3,4,5,6,7,8,9,10};
vector<int>::iterator it;
auto beginning = vi1.begin();

for(it = vi1.end()-1; it >= beginning; it--){
cout << *it << " ";
}
cout << endl;

it = beginning + 7;
cout << *it << " ";
it -= 3;
cout << *it << " ";
it += 4;
cout << *it << " ";
cout << endl;
return 0;
}
10 9 8 7 6 5 4 3 2 1 

8 5 9 

__________________________________________________________________________________________________________________________________________
#include<iostream>
#include<list>
using namespace std;

int main(int argc, char ** argv){
cout << "list of ints from initialize list (C++11)" << endl;
list<int> li1 = {1,2,3,4,5,6,7,8,9,10};
cout << "size: " << li1.size() << endl;
cout << "front: " << li1.front() << endl;
cout << "back: " << li1.back() << endl;

cout << "push_back 47:" << endl;
li1.push_back(47);
cout << "size: " << li1.size() << endl;
cout << "back: " << li1.back() << endl;

cout << "range-based iterator (C++11): " << endl;
for(int v : li1){
cout << v << " ";
}
cout << endl << endl;

list<int>::iterator it1 = li1.begin();
list<int>::iterator it2 = li1.begin();
cout << "insert 112 before 5 " << endl;
while(*it1 != 5)
++it1;
li1.insert(it1, 112);
cout << "erase 7 " << endl;
while(*it2 != 7)
++it2;
li1.erase(it2);
for(int v : li1){
cout << v << " ";
}
cout << endl << endl;

it1 = li1.begin();
it2= li1.begin();
cout << "erase 112 to 8 " << endl;
while(*it1 != 112) ++it1;
while(*it2 != 8) ++it2;
cout << *it1 << " " << *it2 << endl;
li1.erase(it1, it2); //*it2 not included
for(int v : li1){
cout << v << " ";
}
cout << endl << endl;

cout << "list from C-array:" << endl;
const static int size = 10;
int ia[size] = {1,2,3,4,5,6,7,8,9,10};
list<int> li2(ia, ia+size);
for(int v: li2){
cout << v << " ";
}
cout << endl;

cout << "list of strings, from argc/argv list: " << endl;
list<string> args(argv, argv+argc);
cout << "while pop" << endl;
while(args.size() > 0){
cout << args.front() << endl;
args.pop_front();
}
return 0;
}
list of ints from initialize list (C++11)

size: 10

front: 1

back: 10

push_back 47:

size: 11

back: 47

range-based iterator (C++11): 

1 2 3 4 5 6 7 8 9 10 47 

insert 112 before 5 

erase 7 

1 2 3 4 112 5 6 8 9 10 47 

erase 112 to 8 

112 8

1 2 3 4 8 9 10 47 

list from C-array:

1 2 3 4 5 6 7 8 9 10 

list of strings, from argc/argv list: 

while pop

F:\workspace\CppWorking\Debug\CppWorking.exe

one

two

three

set:


std::set::insert

C++98

C++11



single element (1)
pair<iterator,bool> insert (const value_type& val);
pair<iterator,bool> insert (value_type&& val);

with hint (2)
iterator insert (const_iterator position, const value_type& val);
iterator insert (const_iterator position, value_type&& val);

range (3)
template <class InputIterator>
void insert (InputIterator first, InputIterator last);

initializer list (4)
void insert (initializer_list<value_type> il);


std::multiset::insert

C++98

C++11



single element (1)
iterator insert (const value_type& val);
iterator insert (value_type&& val);

with hint (2)
iterator insert (const_iterator position, const value_type& val);
iterator insert (const_iterator position, value_type&& val);

range (3)
template <class InputIterator>
void insert (InputIterator first, InputIterator last);

initializer list (4)
void insert (initializer_list<value_type> il);

#include<iostream>
#include<set>
using namespace std;

int main(int argc, char** argv){
cout << "set of strings from initializer list(C++11):" << endl;
set<string> strset = {"one", "two", "three", "four", "five"};
cout << "size: " << strset.size() << endl;
for(string s: strset){
cout << s << " ";
}
cout << endl << endl;

cout << "insert element \"six\"" << endl;
strset.insert("six");
for(string s : strset) {
cout << s << " ";
}
cout << endl << endl;
cout << "insert duplicate element \"five\"" << endl;
pair<set<string>::iterator, bool> rvinsert = strset.insert("five");
bool & insertSuccess = rvinsert.second;
if(insertSuccess){
for(string s: strset){
cout << s << " ";
}
}else{
cout << "insert failed";
}
cout << endl << endl;

cout << "find and erase element \"six\"" << endl;
set<string>::iterator it = strset.find("six");
if(it != strset.end()){
cout << "found " << *it << endl;
strset.erase(it);
}else {
cout << "not found"  << endl;
}

for(string s: strset){
cout << s << " ";
}
cout << endl;

return 0;
}
set of strings from initializer list(C++11):

size: 5

five four one three two 

insert element "six"

five four one six three two 

insert duplicate element "five"

insert failed

find and erase element "six"

found six

five four one three two 

multiset:

#include<iostream>
#include<set>
using namespace std;

int main(int argc, char** argv){
cout << "set of strings from initializer list(C++11):" << endl;
multiset<string> strset = {"one", "two", "three", "four", "five"};
cout << "size: " << strset.size() << endl;
for(string s: strset){
cout << s << " ";
}
cout << endl << endl;

cout << "insert element \"six\"" << endl;
strset.insert("six");
for(string s : strset) {
cout << s << " ";
}
cout << endl << endl;

cout << "insert duplicate element \"five\"" << endl;
strset.insert("five");
for(string s : strset) {
cout << s << " ";
}
cout << endl << endl;

cout << "find and erase element \"five\"" << endl;
auto it = strset.find("five");
if(it != strset.end()){
cout << "found " << *it << endl;
strset.erase(it);
}else {
cout << "not found" << endl;
}
for(string s: strset){
cout << s << " ";
}
cout << endl;

return 0;
}
set of strings from initializer list(C++11):

size: 5

five four one three two 

insert element "six"

five four one six three two 

insert duplicate element "five"

five five four one six three two 

find and erase element "five"

found five

five four one six three two 

map:

#include<iostream>
#include<map>
using namespace std;

int main(int argc, char ** argv){
cout << "map of strings from initializer list(C++11):" << endl;
map<string, string> strmap = {
{"George", "Father"},
{"Ellen", "Mother"},
{"Ruth", "Daughter"},
{"Spike", "Neighbor Wang's son"}
};
map<string, string>::iterator it;
cout << "size is " << strmap.size() << endl;
cout << "check a couple of key/value pairs" << endl;
cout << "George is " << strmap["George"] << endl;
cout << "Ellen is " << strmap.find("Ellen")->second << endl;
cout << endl;

cout << "iterate the set" << endl;
for(it = strmap.begin(); it != strmap.end(); ++it){
cout << it->first << " is " << it->second << endl;
}
cout << endl;

cout << "insert an element" << endl;
strmap.insert(pair<string, string>("Luke", "Neighbor") );
//strmap.insert({"Luke", "Neighbor"});
cout << "inserted - size is " << strmap.size() << endl;
for(pair<string, string> v: strmap){
cout << v.first << " is " << v.second << endl;
}
cout << endl;

cout << "insert a duplicate" << endl;
strmap.insert({"Luke", "Neighbor wang"});
cout << "after insert size is " << strmap.size() << endl;
for(auto v: strmap){
cout << v.first << " is " << v.second << endl;
}
cout << endl;

cout << "find and erase an element" << endl;
it = strmap.find("Luke");
if(it != strmap.end()){
cout << "found Luke: " << it->second << endl;
strmap.erase(it);
cout << "erased - size is " << strmap.size() << endl;
} else{
cout << "not found" << endl;
}
for(auto v: strmap){
cout << v.first << " is " << v.second << endl;
}
cout << endl;

return 0;
}
map of strings from initializer list(C++11):

size is 4

check a couple of key/value pairs

George is Father

Ellen is Mother

iterate the set

Ellen is Mother

George is Father

Ruth is Daughter

Spike is Neighbor Wang's son

insert an element

inserted - size is 5

Ellen is Mother

George is Father

Luke is Neighbor

Ruth is Daughter

Spike is Neighbor Wang's son

insert a duplicate

after insert size is 5

Ellen is Mother

George is Father

Luke is Neighbor

Ruth is Daughter

Spike is Neighbor Wang's son

find and erase an element

found Luke: Neighbor

erased - size is 4

Ellen is Mother

George is Father

Ruth is Daughter

Spike is Neighbor Wang's son

multimap:
#include<iostream>
#include<map>
using namespace std;

int main(int argc, char ** argv){
cout << "map of strings from initializer list(C++11):" << endl;
multimap<string, string> strmap = {
{"George", "Father"},
{"Ellen", "Mother"},
{"Ruth", "Daughter"},
{"Spike", "Neighbor Wang's son"}
};
multimap<string, string>::iterator it;
cout << "size is " << strmap.size() << endl;
cout << "check a couple of key/value pairs" << endl;
//cout << "George is " << strmap["George"] << endl; //unvalid in multimap
cout << "Ellen is " << strmap.find("Ellen")->second << endl;
cout << endl;

cout << "iterate the set" << endl;
for(it = strmap.begin(); it != strmap.end(); ++it){
cout << it->first << " is " << it->second << endl;
}
cout << endl;

cout << "insert an element" << endl;
strmap.insert(pair<string, string>("Luke", "Neighbor") );
//strmap.insert({"Luke", "Neighbor"});
cout << "inserted - size is " << strmap.size() << endl;
for(pair<string, string> v: strmap){
cout << v.first << " is " << v.second << endl;
}
cout << endl;

cout << "insert a duplicate" << endl;
strmap.insert({"Luke", "Neighbor wang"});
cout << "after insert size is " << strmap.size() << endl;
for(auto v: strmap){
cout << v.first << " is " << v.second << endl;
}
cout << endl;

cout << "find and erase an element" << endl;
it = strmap.find("Luke");
if(it != strmap.end()){
cout << "found Luke: " << it->second << endl;
strmap.erase(it);
cout << "erased - size is " << strmap.size() << endl;
} else{
cout << "not found" << endl;
}
for(auto v: strmap){
cout << v.first << " is " << v.second << endl;
}
cout << endl;

return 0;
}
map of strings from initializer list(C++11):

size is 4

check a couple of key/value pairs

Ellen is Mother

iterate the set

Ellen is Mother

George is Father

Ruth is Daughter

Spike is Neighbor Wang's son

insert an element

inserted - size is 5

Ellen is Mother

George is Father

Luke is Neighbor

Ruth is Daughter

Spike is Neighbor Wang's son

insert a duplicate

after insert size is 6

Ellen is Mother

George is Father

Luke is Neighbor

Luke is Neighbor wang

Ruth is Daughter

Spike is Neighbor Wang's son

find and erase an element

found Luke: Neighbor

erased - size is 5

Ellen is Mother

George is Father

Luke is Neighbor wang

Ruth is Daughter

Spike is Neighbor Wang's son

queue:
queue<int, list<int>> //first type is the type of things the list is made up of; second type is the container being adapted

the default underlying container of queue is deque.

#include<iostream>
#include<list>
#include<queue>

using namespace std;

int main(int argc, char ** argv){
cout << "initialize queue from list" << endl;
list<int> li = {1,2,3,4,5};
queue<int, list<int> > ql(li);

cout << "li has " << li.size() << " entries; " <<
"ql has " << ql.size() << " entries." << endl;
cout << "pop all from ql" << endl;
while(!ql.empty()){
cout << ql.front() << " ";
ql.pop();
}
cout << endl;
cout << "li has " << li.size() << " entries; " <<
"ql has " << ql.size() << " entries." << endl;

cout << "contents of li after ql is emptied:" << endl;
for(auto it = li.begin(); it != li.end(); ++it){
cout << *it << " ";
}
cout << endl;

cout << "push strings onto qd" << endl;
queue<string> qd; // default queue uses deque object
qd.push("one");
qd.push("two");
qd.push("three");
qd.push("four");
qd.push("five");
cout <<"size of qd: " << qd.size() << endl;

cout<< "pop all from qd" << endl;
while(!qd.empty()){
cout << qd.front() << " ";
qd.pop();
}
cout << endl;
cout << "size of qd: " << qd.size() << endl;
return 0;
}
initialize queue from list

li has 5 entries; ql has 5 entries.

pop all from ql

1 2 3 4 5 

li has 5 entries; ql has 0 entries.

contents of li after ql is emptied:

1 2 3 4 5 

push strings onto qd

size of qd: 5

pop all from qd

one two three four five 

size of qd: 0

stack:
// default stack uses deque object
#include<iostream>
#include<list>
#include<stack>

using namespace std;

int main(int argc, char ** argv){
cout << "initialize queue from list" << endl;
list<int> li = {1,2,3,4,5};
stack<int, list<int> > sl(li);

cout << "li has " << li.size() << " entries; " <<
"sl has " << sl.size() << " entries." << endl;
cout << "pop all from sl" << endl;
while(!sl.empty()){
cout << sl.top() << " ";
sl.pop();
}
cout << endl;
cout << "li has " << li.size() << " entries; " <<
"sl has " << sl.size() << " entries." << endl;

cout << "contents of li after sl is emptied:" << endl;
for(int i: li){
cout << i << " ";
}
cout << endl;

cout << "push strings onto qd" << endl;
stack<string> sd; // default queue uses deque object
sd.push("one");
sd.push("two");
sd.push("three");
sd.push("four");
sd.push("five");
cout <<"size of qd: " << sd.size() << endl;

cout<< "pop all from sd" << endl;
while(!sd.empty()){
cout << sd.top() << " ";
sd.pop();
}
cout << endl;
cout << "size of sd: " << sd.size() << endl;
return 0;
}
initialize queue from list

li has 5 entries; sl has 5 entries.

pop all from sl

5 4 3 2 1 

li has 5 entries; sl has 0 entries.

contents of li after sl is emptied:

1 2 3 4 5 

push strings onto qd

size of qd: 5

pop all from qd

five four three two one 

size of sd: 0

deque container:
vector + double ended queue. Unlike vector, it can rapidly pushing things at front and at the end.

#include <iostream>
#include <deque>
using namespace std;

int main( int argc, char ** argv ) {
// from initializer list (C++11)
cout << "deque from initializer list (C++11): " << endl;
deque<int> dq1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
cout << "size: " << dq1.size() << endl;
cout << "front: " << dq1.front() << endl;
cout << "back: " << dq1.back() << endl;
cout << "insert 42 at begin + 5: " << endl;
dq1.insert(dq1.begin() + 5, 42);
cout << "size: " << dq1.size() << endl;
cout << "dq1[5]: " << dq1[5] << endl;
cout << "erase at begin + 5: " << endl;
dq1.erase(dq1.begin() + 5);
cout << "size: " << dq1.size() << endl;
cout << "dq1[5]: " << dq1[5] << endl;

cout << "push_back 47: " << endl;
dq1.push_back(47);
cout << "size: " << dq1.size() << endl;
cout << "dq1.back() " << dq1.back() << endl;

cout << "push_front 192: " << endl;
dq1.push_front(192);
cout << "size: " << dq1.size() << endl;
cout << "dq1.front() " << dq1.front() << endl;

// range-based iterator (C++11)
cout << "range-based iterator (C++11): " << endl;
for(int & v : dq1) {
cout << v << " ";
}
cout << endl << endl;

cout << "dq1.pop_front() " << endl;
dq1.pop_front();
cout << "size: " << dq1.size() << endl;
cout << "dq1.pop_back() " << endl;
dq1.pop_back();
cout << "size: " << dq1.size() << endl;
for(int & v : dq1) {
cout << v << " ";
}

return 0;
}
deque from initializer list (C++11): 

size: 10

front: 1

back: 10

insert 42 at begin + 5: 

size: 11

dq1[5]: 42

erase at begin + 5: 

size: 10

dq1[5]: 6

push_back 47: 

size: 11

dq1.back() 47

push_front 192: 

size: 12

dq1.front() 192

range-based iterator (C++11): 

192 1 2 3 4 5 6 7 8 9 10 47 

dq1.pop_front() 

size: 11

dq1.pop_back() 

size: 10

1 2 3 4 5 6 7 8 9 10 

string:
#include <iostream>
#include <string>
using namespace std;

int main( int argc, char ** argv ) {
string s1 = "This is a string";
string::iterator it;

// size & length
cout << "size is same as length: " << s1.length() << endl;

// + for concatenation
cout << "concatenated strings: ";
string s2 = "this is also a string";
cout << s1 + ":" + s2 << endl;

// compare
cout << "is s1 == s2? " << (s1 == s2 ? "yes" : "no") << endl;
cout << "copy-assign s2 = s1" << endl;
s2 = s1;
cout << "is s1 == s2? " << (s1 == s2 ? "yes" : "no") << endl;

// iteration
cout << "each character: ";
for(it = s1.begin(); it != s1.end(); it++) {
cout << *it << " ";
}
cout << endl;

// for(char c: s1){
// cout << c << " ";
// }

// insert & erase with an iterator
it = s1.begin() + 5;
s1.insert(it, 'X');
cout << "after insert: " << s1 << endl;

it = s1.begin() + 5;
s1.erase(it);
cout << "after erase: " << s1 << endl;

// replace
s1.replace(5, 2, "ain't");
cout << "after replace: " << s1 << endl;

// substr
cout << "substr: " << s1.substr(5, 5) << endl;

// find
size_t pos = s1.find("s");
cout << "find first \"s\" in s1 (pos): " << pos << endl;
cout << "substr at pos: " << s1.substr(pos) << endl;

// rfind
pos = s1.rfind("s");
cout << "find last \"s\" in s1 (pos): " << pos << endl;
cout << "substr at pos: " << s1.substr(pos) << endl;

return 0;
}size is same as length: 16

concatenated strings: This is a string:this is also a string

is s1 == s2? no

copy-assign s2 = s1

is s1 == s2? yes

each character: T h i s   i s   a   s t r i n g 

after insert: This Xis a string

after erase: This is a string

after replace: This ain't a string

substr: ain't

find first "s" in s1 (pos): 3

substr at pos: s ain't a string

find last "s" in s1 (pos): 13

substr at pos: string

algorithms:

#include <iostream>
#include <vector>
#include <locale>
#include <algorithm>
using namespace std;

// functor for count_if
class strhas {
char needle;
strhas(){}
public:
strhas(char c) : needle(c) {}
bool operator () ( string & );
};
bool strhas::operator() ( string & haystack ) {
return haystack.find_first_of(needle) != haystack.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;
string s1 = "big light in sky slated to appear in east";

// count
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();

// find
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;
}

// equal
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;

// search
string match = "slated";
cout << "string is \"" << s1 << "\", search term is \"" << match << "\"" << endl;
cout << "search: ";
string::iterator search_it = search(s1.begin(), s1.end(), match.begin(), match.end());
if(search_it != s1.end()) {
cout << "search term found at position " << size_t( search_it - s1.begin() ) << endl;
} else {
cout << "search term not found" << endl;
}

// show vs before count_if
cout << "vs is: ";
for( string s : vs ) cout << s << " ";
cout << endl;

// count_if
cout << "count_if vs has 's' (functor): ";
cout << count_if(vs.begin(), vs.end(), strhas('s') ) << endl;

// C++11 count_if with lambda expression
cout << "count_if vs has 's' (lambda): ";
cout << count_if(vs.begin(), vs.end(),
[](string & s) { return s.find_first_of('s') != s.npos; }
) << endl;

// for_each
cout << "for_each uppercase: ";
for_each(vs.begin(), vs.end(), [](string & s){ cout << uppercase(s) << " "; });
cout << endl;

// transform
cout << "transform: " << endl;
vector<int> vi2;
cout << "vi before transformation: ";
for( int i : vi ) cout << i << " ";
cout << endl;
vi2.resize(vi.size()); // make space for transformation
transform(vi.begin(), vi.end(), vi2.begin(), [](int i){ 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){ return i + j; });
cout << "vi2 after second transformation: ";
for( int i : vi2 ) cout << i << " ";
cout << endl;

cout << "vi after all transformations: ";
for( int i : vi ) cout << i << " ";
cout << endl;

cout << "string before initial cap transformation: " << s1 << endl;
char last = 0;
transform(s1.begin(), s1.end(), s1.begin(), [&last](char c) {
if(last == ' ' || last == 0) { last = c; return toupper(c); }
else { last = 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 

vi after all transformations: 1 2 3 4 5 6 7 8 9 10 

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: