第三章 标准库类型
code:
// 第三章 标准库类型 // 1、命名空间的using声明 ------------------------------------------- #include <string> #include <iostream> // using declarations states our intent to use these names from the namespace std using std::cin; using std::string; int main() { string s; // ok: string is now a synonym for std::string cin >> s; // ok: cin is now a synonym for std::cin // cout << s; // error: no using declaration; we must use full name std::cout << s; // ok: explicitly use cout from namepsace std } // 虽然书中建议这么做,但不够实用 #include <iostream> // using declarations for names from the standard library using std::cin; using std::cout; using std::endl; int main() { cout << "Enter two numbers:" << endl; int v1, v2; cin >> v1 >> v2; cout << "The sum of " << v1 << " and " << v2 << " is " << v1 + v2 << endl; return 0; } // 我建议先这么用: #include <iostream> using namespace std; int main() { cout << "Enter two numbers:" << endl; int v1, v2; cin >> v1 >> v2; cout << "The sum of " << v1 << " and " << v2 << " is " << v1 + v2 << endl; return 0; } // 2、标准库string类型 ----------------------------------------------- //几种初始化 string 对象的方式 #include <iostream> #include <string> using namespace std; int main() { string s1; string s2(s1); string s3("value"); string s4(9,'c'); cout << s1 << endl; cout << s2 << endl; cout << s3 << endl; cout << s4 << endl; if(s1=="") cout<<"s1 is the empty string"<<endl; return 0; } #include <iostream> #include <string> using namespace std; int main() { string s; // empty string cin >> s; // read whitespace-separated string into s cout << s << endl; // write s to the output return 0; } // 把多个操作放一起 #include <iostream> #include <string> using namespace std; int main() { string s1,s2; cin >> s1 >> s2; cout << s1 << s2 << endl; return 0; } // Hello World! // 读到文件尾。注意,窗口调试时,可以用 Ctrl+z 来模拟文件尾 #include <iostream> #include <string> using namespace std; int main() { string word; // read until end-of-file, writing each word to a new line while(cin >> word) cout << word << endl; return 0; } // getline #include <iostream> #include <string> using namespace std; int main() { string line; while(getline(cin, line)) cout << line << endl; return 0; } /* There is an additional useful string IO operation: getline. This is a function that takes both an input stream and a string. The getline function reads the next line of input from the stream and stores what it read, not including the newline, in its string argument. Unlike the input operator, getline does not ignore leading newlines. Whenever getline encounters a newline, even if it is the first character in the input, it stops reading the input and returns. The effect of encountering a newline as the first character in the input is that the string argument is set to the empty string. 这一段的翻译问题很大,不知所云。比如说:getline 函数从输入流的下一行读取。。。是完全错误的。试着重新翻译一下: 还有另外一种非常有用的字符串输入输出操作:getline。这个函数有两个参数:输入流和字符串变量。 getline函数从输入流中读到换行符时,会把当前行的输入字符串保存到字符串变量参数中(注意,不包括换行符) 不像一般的输入操作,getline不会忽略掉空行(一般的输入操作,指cin字符串,会把空行当成分隔符) 当getline碰到空行时,不会把换行符当成第一个字符输入,它马上停止读取输入并返回。 当getline读取空行时,字符串变量参数会被设置成空串(empty string)。 (所以用getline读取到的字符串,永远不会含有换行符) */ /* 读取换行符,向来是Cer or Cpper 的纠结问题之一。 比如有一个文件,文件内容有两行,如下: e f abc de fg 要求我们编程,先读取两个字符,然后读取一行字符串。 程序可能会这样: */ #include <iostream> #include <string> using namespace std; int main() { char a,b; string line; cin >> a >> b; getline(cin,line); cout << a << b << endl; cout << line << endl; return 0; } // 那恭喜你,本来想读取到的字符串,是一个空串。应该这样: #include <iostream> #include <string> using namespace std; int main() { char a,b; // string,int... 当读取完字符、整数、字符串等,再读取一行字符串时,都会碰到这问题 string line; cin >> a >> b; getline(cin,line); //读取的是换行符,line中是空串。当然有其它很多纯C的方法:getchar(), scanf(... getline(cin,line); //这次,才真读取到了第二行 cout << a << b << endl; cout << line << endl; return 0; } // string 对象的操作,自编 #include <iostream> #include <string> using namespace std; int main() { string s,st; if(s.empty()) cout<<"empty string"<<endl; cin >> s; if(0!=s.size()) // or !s.empty() cout<<s.size()<<' '<<s[0]<<endl; cin >> st; cout << s+st << endl; return 0; } // string 的 size 和 empty 操作 #include <iostream> #include <string> using namespace std; int main() { string st("The expense of spirit\n"); cout << "The size of " << st << "is " << st.size() << " characters, including the newline" << endl; return 0; //一个换行符长度,算1 } // string::size_type #include <iostream> #include <string> using namespace std; int main() { string s("\n\n"); string::size_type st; st=s.size(); cout << st << endl; cout << sizeof(st) << endl; return 0; } // ==, >=, ... #include <iostream> #include <string> using namespace std; int main() { string big = "big", small = "small"; string s1 = big; // s1 is a copy of big if(big == small) // false // ... if(big <= s1) // true, they're equal, so big is less than or equal to s1 // ... return 0; } // + #include <iostream> #include <string> using namespace std; int main() { string s1 = "hello"; // no punctuation string s2 = "world"; string s3 = s1 + ", "; // ok: adding a string and a literal // string s4 = "hello" + ", "; // error: no string operand string s5 = s1 + ", " + "world"; // ok: each + has string operand // string s6 = "hello" + ", " + s2; // error: can't add string literals return 0; } #include <iostream> #include <string> using namespace std; int main() { string str("some string"); for(string::size_type ix = 0; ix != str.size(); ++ix) cout << str[ix] << endl; for(string::size_type ix = 0; ix != str.size(); ++ix) str[ix] = '*'; cout << str << endl; return 0; } // 字符操作函数 #include <iostream> #include <string> using namespace std; int main() { string s("Hello World!!!"); string::size_type punct_cnt = 0; // count number of punctuation characters in s for(string::size_type index = 0; index != s.size(); ++index) if(ispunct(s[index])) //是标点符号 ++punct_cnt; cout << punct_cnt << " punctuation characters in " << s << endl; // convert s to lowercase for(string::size_type index = 0; index != s.size(); ++index) s[index] = tolower(s[index]); // 变小写 cout << s << endl; return 0; } // 3、标准库vector类型 --------------------------------------------------------- // Ways to Initialize a vector #include <iostream> #include <string> #include <vector> using namespace std; int main() { vector<int> v1; // 默认为空 vector<int> v2(v1); vector<int> v3(3,1); vector<int> v4(3); cout << v3[0] << endl; cout << v4[0] << endl; cout << v3[10] << endl; // just test return 0; } // in book #include <iostream> #include <string> #include <vector> using namespace std; int main() { vector < int > ivec1; // ivec1 holds objects of type int vector < int > ivec2(ivec1); // ok: copy elements of ivec1 into ivec2 // vector < string > svec(ivec1); // error: svec holds strings, not ints vector < int > ivec4(10, -1); // 10 elements, each initialized to -1 vector < string > svec(10, "hi!"); // 10 strings, each initialized to "hi!" cout << sizeof( ivec4 ) << endl; // sizeof 失灵中。。 return 0; } #include <iostream> #include <string> #include <vector> using namespace std; int main() { // read words from the standard input and store them as elements in a vector string word; vector < string > text; // empty vector while(cin >> word) { text.push_back(word); // append word to text } return 0; } #include <iostream> #include <string> #include <vector> using namespace std; int main() { vector<int> ivec(3,1); // reset the elements in the vector to zero for (vector<int>::size_type ix = 0; ix != ivec.size(); ++ix) ivec[ix] = 0; return 0; } // 错误的方法。编译不会有问题,运行时就错误了。 #include <iostream> #include <string> #include <vector> using namespace std; int main() { vector<int> ivec; // empty vector for (vector<int>::size_type ix = 0; ix != 10; ++ix) ivec[ix] = ix; // disaster: ivec has no elements //for (vector<int>::size_type ix = 0; ix != 10; ++ix) // cout << ivec[ix] << endl; return 0; } // 正确写法 #include <iostream> #include <string> #include <vector> using namespace std; int main() { vector<int> ivec; // empty vector for (vector<int>::size_type ix = 0; ix != 10; ++ix) ivec.push_back(ix); // ok for (vector<int>::size_type ix = 0; ix != 10; ++ix) cout << ivec[ix] << endl; for (vector<int>::size_type ix = 0; ix != 10; ++ix) cout << ivec.at(ix); //这种方法书中木介绍 return 0; } // 4、迭代器简介 -------------------------------------------------------------------- #include <iostream> #include <string> #include <vector> using namespace std; int main() { vector < int > ivec(3, 1); // reset all the elements in ivec to 0 for(vector < int > ::size_type ix = 0; ix != ivec.size(); ++ix) ivec[ix] = 0; // equivalent loop using iterators to reset all the elements in ivec to 0 for(vector < int > ::iterator iter = ivec.begin(); iter != ivec.end(); ++iter) *iter = 0; // set element to which iter refers to 0 for(vector < int > ::iterator iter = ivec.begin(); iter != ivec.end(); ++iter) cout << *iter << endl; // 遍历输出 return 0; } #include <iostream> #include <string> #include <vector> using namespace std; int main() { vector < string > text(3, "hi"); // use const_iterator because we won't change the elements for(vector < string > ::const_iterator iter = text.begin(); iter != text.end(); ++iter) cout << *iter << endl; // print each element in text // for(vector < string > ::const_iterator iter = text.begin(); iter != text.end(); ++iter) ; //*iter = " "; // error: *iter is const // const_iterator指向的值,是不可改变的 // return 0; } // const ... #include <iostream> #include <string> #include <vector> using namespace std; int main() { vector < int > nums(10); // nums is nonconst const vector < int > ::iterator cit = nums.begin(); // 这是个 const iterator *cit = 1; // ok: cit can change its underlying element ; // ++cit; // error: can't change the value of cit。 iterator不能改变 const vector < int > nines(10, 9); // cannot change elements in nines // error: cit2 could change the element it refers to and nines is const // const vector < int > ::iterator cit2 = nines.begin(); // ok: it can't change an element value, so it can be used with a const vector<int> vector < int > ::const_iterator it = nines.begin(); ; //*it = 10; // error: *it is const ++it; // ok: it isn't const so we can change its value return 0; } // Iterator Arithmetic #include <iostream> #include <string> #include <vector> using namespace std; int main() { vector<int>::iterator iter1,iter2,iter; vector < int > v(3, 1); iter=v.begin(); iter=iter+2; cout << *iter << endl; iter1=v.begin(); iter2=v.end(); vector<int>::difference_type dt; dt=iter1-iter2; cout << dt << endl; int t; // 嗯,这样貌似也可以 t=iter1-iter2; cout << t << endl; return 0; } // 5、标准库bitset -------------------------------------------------------------- // 初始化bitset的四种方法 #include <iostream> #include <string> #include <vector> #include <bitset> using namespace std; int main() { const unsigned n=32; bitset<n> a; bitset<n> b(255); bitset<n> c(string("11111111")); bitset<n> d(string("11111111"),1,2); return 0; } // 用unsigned值初始化bitset对象 #include <iostream> #include <string> #include <vector> #include <bitset> using namespace std; int main() { // bitvec1 is smaller than the initializer bitset < 16 > bitvec1(0xffff); // bits 0 ... 15 are set to 1 // bitvec2 same size as initializer bitset < 32 > bitvec2(0xffff); // bits 0 ... 15 are set to 1; 16 ... 31 are 0 // on a 32-bit machine, bits 0 to 31 initialized from 0xffff bitset < 128 > bitvec3(0xffff); // bits 32 through 127 initialized to zero // out 从低位到高位,与人们的视觉习惯相反 for( int i=0; i!=128; ++i ) cout << bitvec3[i]; return 0; } // 用 string 对象初始化 bitset 对象 #include <iostream> #include <string> #include <vector> #include <bitset> using namespace std; int main() { string strval("1100"); bitset<32> bitvec(strval); for( int i=0; i!=32; ++i ) cout << bitvec[i]; cout << endl; string str("0111111000000011001101"); bitset<32> bitvec5(str, 0, 6); // 6 bits starting at str[0], 111111 bitset<32> bitvec6(str, str.size()-4); // use last 4 characters // 统一法则:为了符合人们的视觉习惯,在字符右边的,靠低位 // 以下屏幕输出时,低位在左边 for( int i=0; i!=32; ++i ) cout << bitvec5[i]; cout << endl; for( int i=0; i!=32; ++i ) cout << bitvec6[i]; cout << endl; return 0; } // 直接输出更清楚 #include <iostream> #include <string> #include <vector> #include <bitset> using namespace std; int main() { string strval("1100"); bitset<32> bitvec(strval); cout << bitvec << endl; string str("0111111000000011001101"); bitset<32> bitvec5(str, 0, 6); // 6 bits starting at str[0], 111111 cout << bitvec5 << endl; bitset<32> bitvec6(str, str.size()-4); // use last 4 characters cout << bitvec6 << endl; return 0; } //bitset 对象上的操作 #include <iostream> #include <string> #include <vector> #include <bitset> using namespace std; int main() { const unsigned n=8; bitset<n> a(string("0010")); if(a.any()) //有1 cout << "have 1" << endl; bitset<n> b(string("0000")); if(b.none()) //木有1 cout << "no 1" << endl; cout << a.count() << endl; //1的个数 cout << a.size() << endl; //2进制位的个数 cout << a[0] << endl; //访问第0位 cout << a.test(0) << endl; //第0位是1吗? b.set(); cout << b << endl; //所有位都设成了1 a.set(0); cout << a << endl; //设置一位为1 b.reset(); cout << b << endl; //都设成0了 a.reset(0); cout << a << endl; //设置一位为0 a.flip(); cout << a << endl; //全部取反 a.flip(0); cout << a << endl; //一位取反 cout << a.to_ulong() << endl; // 转化为十进制整数 return 0; }