(笔记)第三章 标准库类型

1,string,vector,bitset初始化方式、操作

string:

QQ截图20131104195956

QQ截图20131103163509

QQ截图20131103170650

vector:

QQ截图20131104173030

QQ截图20131104173528

bitset:

QQ截图20131104193741

QQ截图20131104194402

QQ截图20131104194410 

2,isspace函数处理中文字符串问题

先看下面代码:

#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。

3,vector的下标操作不能添加元素

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

注意:下标操作符只能对确知已存在的元素进行操作

4,何时使用 const 迭代器的?又在何时使用 const_iterator?解释两者的区别。

const迭代器是迭代器常量,该迭代器本身的值不能修改,即该迭代器在定义时需要初始化,而且初始化之后,不能再指向其他元素。若需要指向固定元素的迭代器,则可以使用const迭代器。

const_iterator是一种迭代器类型,对这种类型的迭代器解引用会得到一个指向const对象的引用,即通过这种迭代器访问到的对象是常量。该对象不能修改,因此,const_iterator类型只能用于读取容器内的元素,不能修改元素的值。若只需遍历容器中的元素而无需修改它们,则可以使用const_iterator。

你可能感兴趣的:(C++,+,中文字符,1),256,unsigned)(c,<=,isspace)