3 C++ Boost 字符,文本
目录: 字符与数值转换 Boost format函数 简单实用 Boost format 输出人员信息 小案例 Boost format 数字处理 Boost format 高级特性 Boost String 处理,大小写转换 Boost String 字符串查找 Boost String 字符串判断式 Boost String 字符串替换: Boost String 字符串分割 Boost String trim剔除两边字符 Boost String regex正则表达式
字符与数值转换
chunli@Linux:~/boost$ cat main.cpp #include <iostream> #include <stdio.h> #include <boost/lexical_cast.hpp> using namespace std; int main() { string s("3.14e12"); double d = boost::lexical_cast<double>(s); printf("%f \n",d); try { int i = strtol("ff",NULL,16);//C 函数 16进制转长××× printf("%d \n",i); //int a = boost::lexical_cast<int>("ff");//转换失败,抛异常 int a = boost::lexical_cast<int>("314");//OK printf("%d \n",a); } catch(boost::bad_lexical_cast &e) { printf("%s \n",e.what()); } string ns = boost::lexical_cast<string>(0xfe); cout << ns <<endl; } chunli@Linux:~/boost$ g++ main.cpp -Wall && ./a.out 3140000000000.000000 255 314 254 chunli@Linux:~/boost$
Boost format函数 简单实用
chunli@Linux:~/boost$ cat main.cpp #include <iostream> #include <iomanip> #include <cassert> #include <boost/format.hpp> namespace MyNS_ForOutput { using std::cout; using std::cerr; using std::string; using std::endl; using std::flush; using boost::format; using boost::io::group; } namespace MyNS_Manips { using std::setfill; using std::setw; using std::hex ; using std::dec ; // gcc-2.95 doesnt define the next ones // using std::showbase ; // using std::left ; // using std::right ; // using std::internal ; } using namespace MyNS_ForOutput; using namespace MyNS_Manips; int main() { //输出Hello 占9个宽度,接着一整空格,再输出3占6个宽度. std::cout << format("%|1$9| %|2$6|") % "Hello" % 3 << std::endl; //参数任意排列 cout << format("%1% %2% %3% %2% %1% \n") % "o" % "oo" % "O"; //输出-23右对齐占5个宽度,输出35左对齐占5个宽度 cout << format("(x,y) = (%1$+5d,%2$-5d) \n") % -23 % 35; cout << format("(x,y) = (%+5d,%-5d) \n") % -23 % 35;//效果同上 cout << format("(x,y) = (%|+5|,%|-5|) \n") % -23 % 35;//效果同上 cout << format("(x,y) = (%|1$+5|,%|2$-5|)\n")% -23 % 35;//效果同上 //弱类型,40.23不会因为%s而报错 cout << format("name=%s,price=%s¥,quantity=%dKG.\n") % "apple" % 4.23 % 50; //设置C++ IO,填充,输出格式,宽度,数据 cout << format("%2% %1% %2%\n") % 919 % group(setfill('X'), hex, setw(4), 15-1) ; //输出不同的进制 cout << format("%1$4d is : %1$#4x, %1$#4o, %1$s,\n") % 18; cout << format("15 -> %%##%#x ") % 15 << endl; std::string s; s= str( format(" %d %d ") % 11 % 22 );//类似sprintf assert( s == " 11 22 "); cout << "assert Ok " << endl; //format的异常,参数过多 try { format(" %1% %1% ") % 101 % 102; } catch (boost::io::too_many_args& exc) { cerr << exc.what() << "\n别担心,这是我精心设计的错误\n"; } //format的异常,参数过少 try { cerr << format(" %|3$| ") % 101; //必须穿3个进来 } catch (boost::io::too_few_args& exc) { cerr << exc.what() << "\n别担心,这是我精心设计的错误\n"; } //忽略异常 format f(" %|3$| "); f.exceptions(boost::io::all_error_bits ^ (boost::io::too_few_args_bit)); f % 101; cout << "f=" << f << endl; cerr << "\nEverything went OK, exiting. \n"; return 0; } chunli@Linux:~/boost$ g++ main.cpp -Wall && ./a.out Hello 3 o oo O oo o (x,y) = ( -23,35 ) (x,y) = ( -23,35 ) (x,y) = ( -23,35 ) (x,y) = ( -23,35 ) name=apple,price=4.23¥,quantity=50KG. XXXe 919 XXXe 18 is : 0x12, 022, 18, 15 -> %##0xf assert Ok boost::too_many_args: format-string referred to fewer arguments than were passed 别担心,这是我精心设计的错误 boost::too_few_args: format-string referred to more arguments than were passed 别担心,这是我精心设计的错误 f= Everything went OK, exiting. chunli@Linux:~/boost$
Boost format 输出人员信息 小案例
chunli@Linux:~/boost$ cat main.cpp #include <iostream> #include <iomanip> #include "boost/format.hpp" using namespace std; using boost::format; using boost::io::group; int main() { //宽度为6,居中显示 cout << format("_%|=6|_") % 1 << endl; vector<string> names(1, "Marc-Fran is Michel"), surname(1,"Durand"), tel(1, "+33 (0) 123 456 789"); names.push_back("Jean"); surname.push_back("de Lattre de Tassigny"); tel.push_back("+33 (0) 987 654 321"); names.push_back("工程师"); surname.push_back("中国杭州"); tel.push_back("+86 134 2967 8754"); for(unsigned int i=0; i<names.size(); ++i) cout << format("%1%, %2%, %|40t|%3%\n") % names[i] % surname[i] % tel[i]; cerr << "\nEverything went OK, exiting. \n"; return 0; } chunli@Linux:~/boost$ g++ main.cpp -Wall && ./a.out _ 1 _ Marc-Fran is Michel, Durand, +33 (0) 123 456 789 Jean, de Lattre de Tassigny, +33 (0) 987 654 321 工程师, 中国杭州, +86 134 2967 8754 Everything went OK, exiting. chunli@Linux:~/boost$
Boost format 数字处理
chunli@Linux:~/boost$ cat main.cpp #include <iostream> #include <iomanip> #include "boost/format.hpp" #if !(BOOST_WORKAROUND(__GNUC__, < 3) && defined(__STL_CONFIG_H) ) // not for broken gcc stdlib #include <boost/io/ios_state.hpp> #else // not as complete, but compatible with gcc-2.95 : void copyfmt(ios& left, const ios& right) { left.fill(right.fill()); left.flags(right.flags() ); left.exceptions(right.exceptions()); left.width(right.width()); left.precision(right.precision()); } namespace boost { namespace io { class ios_all_saver { std::basic_ios<char> ios_; std::ios & target_r; public: ios_all_saver(std::ios& right) : ios_(0), target_r(right) { copyfmt(ios_, right); } ~ios_all_saver() { copyfmt(target_r, ios_); } }; } } // N.S. boost::io // define showpos and noshowpos : class ShowPos { public: bool showpos_; ShowPos(bool v) : showpos_(v) {} }; std::ostream& operator<<(std::ostream& os, const ShowPos& x) { if(x.showpos_) os.setf(ios_base:: showpos); else os.unsetf(ios_base:: showpos); return os; } ShowPos noshowpos(false); ShowPos showpos(true); #endif // -end gcc-2.95 workarounds //---------------------------------------------------------------------------// // *** an exemple of UDT : a Rational class **** class Rational { public: Rational(int n, unsigned int d) : n_(n), d_(d) {} Rational(int n, int d); // convert denominator to unsigned friend std::ostream& operator<<(std::ostream&, const Rational&); private: int n_; // numerator unsigned int d_; // denominator }; Rational::Rational(int n, int d) : n_(n) { if(d < 0) { n_ = -n_; d=-d; } // make the denominator always non-negative. d_ = static_cast<unsigned int>(d); } std::ostream& operator<<(std::ostream& os, const Rational& r) { using namespace std; streamsize n, s1, s2, s3; streamsize w = os.width(0); // width has to be zeroed before saving state. // boost::io::ios_all_saver bia_saver (os); boost::io::basic_oaltstringstream<char> oss; oss.copyfmt(os ); oss << r.n_; s1 = oss.size(); oss << "/" << noshowpos; // a rational number needs only one sign ! s2 = oss.size(); oss << r.d_ ; s3 = oss.size(); n = w - s3; if(n <= 0) { os.write(oss.begin(), oss.size()); } else if(os.flags() & std::ios_base::internal) { std::streamsize n1 = w/2, n2 = w - n1, t; t = (s3-s1) - n2; // is 2d part '/nnn' bigger than 1/2 w ? if(t > 0) { n1 = w -(s3-s1); // put all paddings on first part. n2 = 0; // minimal width (s3-s2) } else { n2 -= s2-s1; // adjust for '/', n2 is still w/2. } os << setw(n1) << r.n_ << "/" << noshowpos << setw(n2) << r.d_; } else { if(! (os.flags() & std::ios_base::left)) { // -> right align. (right bit is set, or no bit is set) os << string(n, ' '); } os.write(oss.begin(), s3); if( os.flags() & std::ios_base::left ) { os << string(n, ' '); } } return os; } int main(){ using namespace std; using boost::format; using boost::io::group; using boost::io::str; string s; Rational r(16, 9); cout << "start ! " << endl; cout << r << endl; // "16/9" cout << showpos << r << ", " << 5 << endl; // "+16/9, +5" cout << format("%02d : [%0+9d] \n") % 1 % r ; // "01 : [+016 / 0009]" cout << format("%02d : [%_+9d] \n") % 2 % Rational(9,160); // "02 : [+9 / 160]" cout << format("%02d : [%_+9d] \n") % 3 % r; // "03 : [+16 / 9]" cout << format("%02d : [%_9d] \n") % 4 % Rational(8,1234); // "04 : [8 / 1234]" cout << format("%02d : [%_9d] \n") % 5 % Rational(1234,8); // "05 : [1234 / 8]" cout << format("%02d : [%09d] \n") % 6 % Rational(8,1234); // "06 : [0008 / 1234]" cout << format("%02d : [%0+9d] \n") % 7 % Rational(1234,8); // "07 : [+1234 / 008]" cout << format("%02d : [%0+9d] \n") % 8 % Rational(7,12345); // "08 : [+07 / 12345]" cerr << "\n\nEverything went OK, exiting. \n"; return 0; } chunli@Linux:~/boost$ g++ main.cpp -Wall && ./a.out start ! 16/9 +16/9, +5 01 : [+016/0009] 02 : [+ 9/ 160] 03 : [+ 16/ 9] 04 : [ 8/1234] 05 : [1234/ 8] 06 : [0008/1234] 07 : [+1234/008] 08 : [+07/12345] Everything went OK, exiting. chunli@Linux:~/boost$
Boost format 高级特性
chunli@Linux:~/boost$ cat main.cpp #include <iostream> #include <iomanip> #include "boost/format.hpp" namespace MyNS_ForOutput { using std::cout; using std::cerr; using std::string; using std::endl; using std::flush; using boost::format; using boost::io::group; } namespace MyNS_Manips { using std::setfill; using std::setw; using std::hex ; using std::dec ; using std::showbase ; using std::left ; using std::right ; using std::internal ; } int main(){ using namespace MyNS_ForOutput; using namespace MyNS_Manips; std::string s; //------------------------------------------------------------------------ // storing the parsed format-string in a 'formatter' : // format objects are regular objects that can be copied, assigned, // fed arguments, dumped to a stream, re-fed arguments, etc... // So users can use them the way they like. format fmter("%1% %2% %3% %1% \n"); fmter % 10 % 20 % 30; cout << fmter; // prints "10 20 30 10 \n" // note that once the fmter got all its arguments, // the formatted string stays available (until next call to '%') // The result is available via function str() or stream's << : cout << fmter; // prints the same string again. // once you call operator% again, arguments are cleared inside the object // and it is an error to ask for the conversion string before feeding all arguments : fmter % 1001; try { cout << fmter; } catch (boost::io::too_few_args& exc) { cout << exc.what() << "\n\t\t***Dont worry, that was planned\n"; } // we just need to feed the last two arguments, and it will be ready for output again : cout << fmter % 1002 % 1003; // prints "1001 1002 1003 1001 \n" cout << fmter % 10 % 1 % 2; // prints "10 1 2 10 \n" //--------------------------------------------------------------- // using format objects // modify the formatting options for a given directive : fmter = format("%1% %2% %3% %2% %1% \n"); fmter.modify_item(4, group(setfill('_'), hex, showbase, setw(5)) );// 这点可以深入看看 cout << fmter % 1 % 2 % 3; // prints "1 2 3 __0x2 1 \n" // bind one of the argumets : fmter.bind_arg(1, 18);// 这点可以深入看看 cout << fmter % group(hex, showbase, 20) % 30; // %2 is 20, and 20 == 0x14 // prints "18 0x14 30 _0x14 18 \n" fmter.modify_item(4, setw(0)); // cancels previous width-5 fmter.bind_arg(1, 77); // replace 18 with 77 for first argument. cout << fmter % 10 % 20; // prints "77 10 20 0xa 77 \n" try { cout << fmter % 6 % 7 % 8; // Aye ! too many args, because arg1 is bound already } catch (boost::io::too_many_args& exc) { cout << exc.what() << "\n\t\t***Dont worry, that was planned\n"; } // clear regular arguments, but not bound arguments : fmter.clear(); cout << fmter % 2 % 3; // prints "77 2 3 0x2 77 \n" // clear_binds() clears both regular AND bound arguments : fmter.clear_binds(); cout << fmter % 1 % 2 % 3; // prints "1 2 3 0x2 1 \n" // setting desired exceptions : fmter.exceptions( boost::io::all_error_bits ^( boost::io::too_many_args_bit ) ); cout << fmter % 1 % 2 % 3 % 4 % 5 % 6 ; // ----------------------------------------------------------- // misc: // unsupported printf directives %n and asterisk-fields are purely ignored. // do *NOT* provide an argument for them, it is an error. cout << format("|%5d| %n") % 7 << endl; // prints "| 7| " cout << format("|%*.*d|") % 7 << endl; // prints "|7|" // truncations of strings : cout << format("%|.2s| %|8c|.\n") % "root" % "user"; // prints "ro u.\n" // manipulators conflicting with format-string : manipulators win. cout << format("%2s") % group(setfill('0'), setw(6), 1) << endl; // prints "000001" cout << format("%2$5s %1% %2$3s\n") % 1 % group(setfill('X'), setw(4), 2) ; // prints "XXX2 1 XXX2\n" // width is 4, as set by manip, not the format-string. // nesting : cout << format("%2$014x [%1%] %2$05s\n") % (format("%05s / %s") % -18 % 7) % group(showbase, -100); // prints "0x0000ffffff9c [-0018 / 7] -0100\n" cout << "\n\nEverything went OK, exiting. \n"; return 0; } chunli@Linux:~/boost$ g++ main.cpp -Wall && ./a.out 10 20 30 10 10 20 30 10 boost::too_few_args: format-string referred to more arguments than were passed ***Dont worry, that was planned 1001 1002 1003 1001 10 1 2 10 1 2 3 __0x2 1 18 0x14 30 _0x14 18 77 10 20 0xa 77 boost::too_many_args: format-string referred to fewer arguments than were passed ***Dont worry, that was planned 77 2 3 0x2 77 1 2 3 0x2 1 1 2 3 0x2 1 | 7| |7| ro u. 000001 XXX2 1 XXX2 0x0000ffffff9c [-0018 / 7] -0100 Everything went OK, exiting. chunli@Linux:~/boost$
Boost String 处理,大小写转换
chunli@Linux:~/workspace/Boost$ cat str.cpp /* * str.cpp * * Created on: 2016年12月2日 * Author: chunli */ #include <string> #include <vector> #include <iostream> #include <iterator> #include <boost/algorithm/string/case_conv.hpp> using namespace std; using namespace boost; int main() { string str1("AbCdEfG"); vector<char> vec1( str1.begin(), str1.end() ); cout << "转换为小写"; to_lower_copy( ostream_iterator<char>(cout), vec1 );//把结构拷贝到IO流 cout << endl; copy(vec1.begin(),vec1.end(),ostream_iterator<char>(cout));//看看数组里面装的是什么 cout << endl; to_lower(vec1 ); //cout << vec1 << endl; cout << "转换为大写" << to_upper_copy( str1 ) << endl;// to_lower( str1 ); cout << "转换为小写" << str1 << endl; return 0; } chunli@Linux:~/workspace/Boost$ g++ str.cpp -Wall && ./a.out 转换为小写abcdefg AbCdEfG 转换为大写ABCDEFG 转换为小写abcdefg chunli@Linux:~/workspace/Boost$
Boost String 字符串查找
chunli@Linux:~/workspace/Boost$ cat main.cpp #include <string> #include <iostream> #include <algorithm> #include <functional> #include <boost/algorithm/string/case_conv.hpp> #include <boost/algorithm/string/find.hpp> using namespace std; using namespace boost; int main() { string str1("abc___cde___efg"); string str2("abc"); //查找"cde",iterator_range 记录的是两个迭代器的位置 iterator_range<string::iterator> range=find_first( str1, string("cde") ); //range 记录的是两个迭代器位置,to_upper开始转换 to_upper( range ); cout << "查找cde,并转换 " << str1 << endl; //查找前3个字符 iterator_range<string::iterator> head=find_head( str1, 3 ); cout << "head(3) of the str1: " << string( head.begin(), head.end() ) << endl; //查找尾部几个字符,有容错功能 head=find_tail( str2, 5 ); cout << "tail(5) of the str2: " << string( head.begin(), head.end() ) << endl; char text[]="hello dolly!"; iterator_range<char*> crange=find_last(text,"ll");//crange记录最后的ll的位置 transform( crange.begin(), crange.end(), crange.begin(), bind2nd( plus<char>(), 2 ) );//ll加2就是nn to_upper( crange ); //crange记录最后的ll的位置 cout << text << endl; return 0; } chunli@Linux:~/workspace/Boost$ g++ main.cpp -Wall && ./a.out 查找cde,并转换 abc___CDE___efg head(3) of the str1: abc tail(5) of the str2: abc hello doNNy! chunli@Linux:~/workspace/Boost$
Boost String 字符串判断式
chunli@Linux:~/workspace/Boost$ cat main.cpp #include <string> #include <iostream> #include <functional> #include <boost/algorithm/string/predicate.hpp> #include <boost/algorithm/string/classification.hpp> #include <boost/bind.hpp> using namespace std; using namespace boost; int main() { string str1("123xxx321"); string str2("abc"); // 判断字符串的开头 cout << "str1 starts with \"123\": " << (starts_with( str1, string("123") )?"true":"false") << endl; // 判断字符串的结尾 cout << "str1 ends with \"123\": " << (ends_with( str1, string("123") )?"true":"false") << endl; // 判断是否存在子串 cout << "str1 contains \"xxx\": " << (contains( str1, string("xxx") )?"true":"false") << endl; // 检测两个字符串是否相等 cout << "str2 equals \"abc\": " << (equals( str2, string("abc") )?"true":"false") << endl; // 检测all里面所有的是不是 符号 if ( all(";.,", is_punct() ) ) { cout << "\";.,\" are all punctuation characters" << endl; } // 检查str1每个字符 是不是属于 str2中 if ( all("abcxxx", is_any_of("xabc") && !is_space() ) ) { cout << "true" << endl; } return 0; } chunli@Linux:~/workspace/Boost$ g++ main.cpp -Wall && ./a.out str1 starts with "123": true str1 ends with "123": false str1 contains "xxx": true str2 equals "abc": true ";.," are all punctuation characters true chunli@Linux:~/workspace/Boost$
Boost String 字符串替换
chunli@Linux:~/workspace/Boost$ cat main.cpp #include <string> #include <iostream> #include <iterator> #include <boost/algorithm/string.hpp> using namespace std; using namespace boost; inline string upcase_formatter( const iterator_range<string::const_iterator>& Replace ) { string Temp(Replace.begin(), Replace.end()); to_upper(Temp); return Temp; } int main() { string str1("abc___cde___efg"); //删除从6到9的字符,不影响str1 cout << erase_range_copy( str1, make_iterator_range(str1.begin()+6, str1.begin()+9) ) << endl; // 从6到9的字符,换成+++,只能处理3位 cout <<replace_range_copy( str1, make_iterator_range(str1.begin()+6, str1.begin()+9), "+++" ) << endl; //把 "cde" 换成"中国杭州",不影响str1 replace_first_copy( ostream_iterator<char>(cout), str1, "cde", "中国杭州" ); cout << endl; // 全部替换,不影响str1 cout << replace_all_copy( str1, "___", "--" ) << endl; cout << replace_all_copy( str1, "___", "----" ) << endl; // 全部删除,不影响str1 cout << erase_all_copy( str1, "___" ) << endl; // 修改第N个字符,影响str1 replace_nth( str1, "_", 4, "+" ); replace_nth( str1, "_", 2, "+" ); cout << str1 << endl; //忽略大小写转换 string str2("abC-xxxx-AbC-xxxx-abc"); cout << find_format_all_copy( str2,first_finder("abc", is_iequal()), upcase_formatter ) << endl; return 0; } chunli@Linux:~/workspace/Boost$ g++ main.cpp -Wall && ./a.out abc______efg abc___+++___efg abc___中国杭州___efg abc--cde--efg abc----cde----efg abccdeefg abc__+cde_+_efg ABC-xxxx-ABC-xxxx-ABC chunli@Linux:~/workspace/Boost$
Boost String 字符串分割
chunli@Linux:~/workspace/Boost$ cat main.cpp #include <string> #include <vector> #include <iostream> #include <iterator> #include <functional> #include <boost/algorithm/string/classification.hpp> #include <boost/algorithm/string/split.hpp> #include <boost/algorithm/string/find_iterator.hpp> using namespace std; using namespace boost; int main() { string str1("abc-*-ABC-*-aBc"); cout << "Before: " << str1 << endl; //忽略大小写查找abc,并打印出来 typedef find_iterator<string::iterator> string_find_iterator; string_find_iterator It = make_find_iterator(str1, first_finder("abc", is_iequal())); for(;It != string_find_iterator();++It) { cout << copy_range<std::string>(*It) << endl; transform(It->begin(), It->end(), It->begin(), bind2nd( plus<char>(), 1 ) );//每个字符加1 } cout << "After: " << str1 << endl; //以 -* 任意字符为分隔符 vector<std::string> ResultCopy; split(ResultCopy, str1, is_any_of("-*"), token_compress_on); for(unsigned int nIndex=0; nIndex<ResultCopy.size(); nIndex++) { cout << nIndex << ":" << ResultCopy[nIndex] << endl; } return 0; } chunli@Linux:~/workspace/Boost$ g++ main.cpp -Wall && ./a.out Before: abc-*-ABC-*-aBc abc ABC aBc After: bcd-*-BCD-*-bCd 0:bcd 1:BCD 2:bCd chunli@Linux:~/workspace/Boost$
Boost String trim剔除两边字符
chunli@Linux:~/workspace/Boost$ cat main.cpp #include <string> #include <iostream> #include <boost/algorithm/string/trim.hpp> #include <boost/algorithm/string/classification.hpp> using namespace std; using namespace boost; int main() { string str1(" 1x x x x1 "); // 去除左边的空格 cout <<"-" << trim_left_copy( str1 ) << "-"<< endl; // 去除右边的空格,直接修改对象 trim_right( str1 ); cout << "-" << str1 << "-" << endl; //去除两边 含< >的任意字符 string str2("<> tr <> im <>"); cout << "-"<< trim_copy_if( str2, is_any_of("< >") ) << "-" << endl; //去除两边包含的任意数字字符 string str3("123abs343"); cout << "-" << trim_copy_if( str3, is_digit() ) << "-" << endl; return 0; } chunli@Linux:~/workspace/Boost$ g++ main.cpp -Wall && ./a.out -1x x x x1 - - 1x x x x1- -tr <> im- -abs- chunli@Linux:~/workspace/Boost$
Boost String regex正则表达式
chunli@Linux:~/workspace/Boost$ cat main.cpp #include <string> #include <iostream> #include <iterator> #include <boost/regex.hpp> #include <boost/algorithm/string/regex.hpp> using namespace std; using namespace boost; int main() { string str1("abc__(456)__123__(123)__cde"); //匹配 (多个数字) 这样的格式 cout << replace_all_regex_copy( str1, regex("\\(([0-9]+)\\)"), string("-$1-") ) << endl; cout << replace_all_regex_copy( str1, regex("\\(([0-9]+)\\)"), string("前$1后") ) << endl; //删除所有的字母 cout << erase_all_regex_copy( str1, regex("[[:alpha:]]+") ) << endl; // /匹配 (多个数字) 这样的格式 replace_all_regex( str1, regex("_(\\([^\\)]*\\))_"), string("-$1-") ); cout << str1 << endl; return 0; } chunli@Linux:~/workspace/Boost$ g++ main.cpp -l boost_regex -Wall && ./a.out abc__-456-__123__-123-__cde abc__前456后__123__前123后__cde __(456)__123__(123)__ abc_-(456)-_123_-(123)-_cde chunli@Linux:~/workspace/Boost$
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。