string:
vector:
bitset:
先看下面代码:
#include "stdafx.h" #include <iostream> #include <string> #include <cctype> using namespace std; int main() { string result; //unsigned char c; char c; string a = "你 好"; int flag = 0; //std::locale::global(std::locale("Chinese_China.936")); for(string::size_type i = 0; i !=a.size(); i++) { c = a[i]; if(isspace(c)) { flag = 1; } else { result += c; } } if(flag) { cout<<result<<endl; } else { cout<<"error"<<endl; return -1; } return 0; }
Vs2010编译运行后会出错: (unsigned)(c + 1) <= 256),发现是isspace出错,于是跟踪到c运行库里看看:
extern __inline int (__cdecl isspace) ( int c ) { if (__locale_changed == 0) { return __fast_ch_check(c, _SPACE); } else { return (_isspace_l)(c, NULL); } }
继续跟踪,__locale_changed的值为0,调用__fast_ch_check,继续下去来到这里:
#if defined (_DEBUG) extern "C" int __cdecl _chvalidator( int c, int mask ) { _ASSERTE((unsigned)(c + 1) <= 256); return _chvalidator_l(NULL, c, mask); }
错误出现在这里:_ASSERTE((unsigned)(c + 1) <= 256);仔细观察函数,它的两个参数c和mask都为int类型,然后汉字的gbk编码是把汉字用两个字节表示,其首字节对应0x81-0xFE。这里就会有个char类型到int类型的转换,在vc2010下,char默认为signed char,这样转换为int后,就会变成一个负数,最后在_ASSERTE又被强制转换成unsigned,此时就产生一个很大的数,错误就此产生。
解决方法:
第一种:Char c 改为: unsigned char c;
第二种:std::locale::global(std::locale(""));
第一种方法不做解释,我们看下第二种到底是什么意思:
一样跟踪进去看下c运行库,实在太复杂,好不容易跟到这段(Microsoft Visual Studio 10.0\VC\crt\src\locale.cpp):
_MRTIMP2_PURE locale __CLRCALL_PURE_OR_CDECL locale::global(const locale& loc) { // change global locale locale _Oldglobal; _BEGIN_LOCK(_LOCK_LOCALE) locale::_Locimp *_Ptr = _Getgloballocale(); if (_Ptr != loc._Ptr) { // set new global locale _DELETE_CRT(_Ptr->_Decref()); _Setgloballocale(_Ptr = loc._Ptr); _Ptr->_Incref(); category _Cmask = _Ptr->_Catmask & all; if (_Cmask == all) setlocale(LC_ALL, _Ptr->_Name._C_str()); else for (int catindex = 0; catindex <= _X_MAX; ++catindex) if ((_CATMASK(catindex) & _Cmask) != 0) setlocale(_CAT_TO_LC(catindex), _Ptr->_Name._C_str()); } return (_Oldglobal); _END_LOCK() }
当传递参数为NULL时,会比较当前应用程序使用的locale和默认的locale是否一致,如果不一致,将会将默认的locale设置为新的locale。这里的默认locale就是:CodePage936。
vector<int> ivec; // empty vector
for (vector<int>::size_type ix = 0; ix != 10; ++ix)
ivec[ix] = ix; // disaster: ivec has no elements
此处ivec被定义为一个空的vector对象,ivec[0],ivec[1]..ivec[n]都是不存在的,无法进行这样的赋值,正确的写法是这样:
for (vector<int>::size_type ix = 0; ix != 10; ++ix)
ivec.push_back(ix); // ok: adds new element with value ix
注意:下标操作符只能对确知已存在的元素进行操作
const迭代器是迭代器常量,该迭代器本身的值不能修改,即该迭代器在定义时需要初始化,而且初始化之后,不能再指向其他元素。若需要指向固定元素的迭代器,则可以使用const迭代器。
const_iterator是一种迭代器类型,对这种类型的迭代器解引用会得到一个指向const对象的引用,即通过这种迭代器访问到的对象是常量。该对象不能修改,因此,const_iterator类型只能用于读取容器内的元素,不能修改元素的值。若只需遍历容器中的元素而无需修改它们,则可以使用const_iterator。