陕西网站建设价格,广告 网站举例,第一次做网站做什么比较好,广告公司做网站前言#xff1a; 为了更好的理解string底层的原理#xff0c;我们将模拟实现string类中常用的函数接口。为了与std里的string进行区分#xff0c;所以用命名空间来封装一个自己的strin类。
string.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1#includeiostream 为了更好的理解string底层的原理我们将模拟实现string类中常用的函数接口。为了与std里的string进行区分所以用命名空间来封装一个自己的strin类。
string.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1#includeiostream
#includeassert.h
#includestring
using namespace std;
namespace manbo
{class string{public://迭代器typedef char* iterator;static size_t npos;//构造函数string(const char* s);//默认构造string();//拷贝构造string(const string s);//析构函数~string();//返回字符串const char* c_str()const ;char operator[](size_t pos);const char operator[](size_t pos)const ;const size_t size()const;iterator begin(){return _str;}iterator end(){return _str _size;}const iterator begin()const {return _str;}const iterator end()const {return _str _size;}void reserve(size_t n 0);void push_back(char ch);string append(const char*s);string operator(const char* s);string operator(char ch);string insert(size_t pos, const char* s);string erase(size_t pos, size_t len npos);size_t find(const char* s, size_t pos 0) const;size_t find(char c, size_t pos 0) const;string substr(size_t pos, size_t len npos) const;void resize(size_t n, char ch \0);void clear();bool operator(const string s) const;bool operator(const string s) const;bool operator(const string s) const;bool operator(const string s) const;bool operator(const string s) const;bool operator!(const string s) const;void swap(string s2);string operator(string temp);private:size_t _size;size_t _capaticy;char* _str;};ostream operator(ostream out, const string s);istream operator(istream in, string s);
}string里有三个私有成员变量 size,capacity,*str分别表示字符数组的有效数据个数容量以及指向字符数组的指针。另外还有一个公有的char类型的指针iterator(迭代器)以及size_t类型的公有静态成员变量npos并初始化值为-1实则会整型的最大值。 string.cpp
namespace manbo
{string::string(const char* s):_size(strlen(s)), _capaticy(_size), _str(new char[_size 1]){memcpy(_str, s,_size1);}string::string():_size(0), _capaticy(0), _str(new char[1]){_str[0] \0;}string::string(const string s){_str new char[s._size 1];_size s._size;_capaticy s._capaticy;memcpy(_str,s._str,s._size1);}string::~string(){delete[] _str;_str nullptr;_size _capaticy 0;}const char* string::c_str()const {return _str;}char string::operator[](size_t pos){assert(pos _size);return _str[pos];}const char string::operator[](size_t pos)const{assert(pos _size);return _str[pos];}const size_t string ::size()const{return _size;}void string::reserve(size_t n){if (n_capaticy){char* temp new char[n 1];memcpy(temp, _str,_size1);_capaticy n;delete[] _str;_str temp;}}void string::push_back(char ch){if (_size_capaticy){reserve(_capaticy 0 ? 4 : 2 * _capaticy);}_str[_size] ch;_str[_size] \0;}string string:: append(const char*s){size_t len strlen(s);if (_sizelen_capaticy){reserve(2 * (_size len));}memcpy(_str _size,s,len1);_size len;return *this;}string string::operator(const char* s){append(s);return *this;}string string::operator(char ch){push_back(ch);return *this;}string string::insert(size_t pos, const char* s){assert(pos 0 pos _size);size_t n strlen(s);size_t len _size n;_size n;if (len_capaticy){reserve(2 *len);}size_t end _size;while (endposend!npos){_str[end n] _str[end];end--;}for (int i 0; i n ; i){_str[pos i] s[i];}return *this;}string string::erase(size_t pos, size_t len){assert(pos _size);;if (lennpos||poslen_size){_str[pos] \0;_size pos;}else{int sum 0;size_t begin pos len;while (begin_size){sum;_str[pos] _str[begin];pos, begin;}_size pos sum;}return *this;}size_t string::find(char c, size_t pos) const{for (size_t i pos; i _size; i){if (_str[i] c)return i;}return npos;}size_t string:: find(const char* s, size_t pos) const{char* temp strstr(_str, s);if (!temp){return npos;}else{return temp-_str ;}}string string::substr(size_t pos, size_t len) const{assert(pos _size);string temp;if (len npos || pos len _size){temp.reserve(_capaticy);for (size_t i pos; i _size; i){temp _str[i];}}else{temp.reserve(len 1);for (size_t i pos; i lenpos; i){temp _str[i];}}return temp;}size_t string::npos -1;void string::resize(size_t n, char ch){if (n_size){_str[n] \0;_size n;}else{reserve(n);for (int i _size; i n; i){_str[i] ch;}_str[n] \0;_size n;}}void string::clear(){_str[0] \0;_size 0;}// hello hello false// hello*** hello false// hello hello** truebool string:: operator(const string s) const{size_t s1, s2;s1 s2 0;while (s1_sizes2s._size){if (_str[s1] s._str[s2])return true;else if (_str[s1] s._str[s2])return false;else{s1, s2;}}if (_sizes.size()){return false;}else if(_size s.size()){return false;}return true;}bool string::operator(const string s) const{return _size s._size 0 (memcmp(s._str, _str, _size));}bool string:: operator(const string s) const{return *this s || *this s;}bool string::operator(const string s) const{return !(*this s);}bool string::operator(const string s) const{return *this s || *this s;}bool string::operator!(const string s) const{return !(*this s);}void string:: swap( string s){std::swap(_str, s._str);std::swap(_capaticy, s._capaticy);std::swap(_size, s._size);}//实现深拷贝string string::operator(string temp){swap(temp);return *this;}
}ostream manbo:: operator(ostream out, const string s)
{for (auto ch:s){out ch;}cout endl;return out;
}
istreammanbo:: operator(istream in, string s)
{s.clear();char ch;ch in.get();while (ch \0 || ch \n){ch in.get();}char buff[128];int i 0;while (ch!\0ch!\n){buff[i] ch;if (i127){buff[i] \0;s buff;i 0;}ch in.get();}if (i0){buff[i] \0;s buff;}return in;
}
string::string(const char* s) 以下是函数的解释 1.这是string类的构造函数它接受一个const char*类型的参数s。这个参数代表一个 C语言 风格的字符串即以 null 终止的字符数组。 2.初始化列表用于在构造函数体执行之前初始化类的成员变量。这里对三个成员变量进行了初始化 2.1strlen(s)计算字符串s的长度不包括 null 终止符。将这个长度赋值给_size成员变量表示字符串的实际字符数。 2.2_capaticy是字符串的容量。在这个实现中容量被设置为与字符串长度相同即_size 2.3new char[_size 1]分配了一块动态内存大小为_size1。这里1是为了存储字符串的 null 终止符\0。将这块内存的指针赋值给_str,_str用于存储实际的字符串内容。 3.构造函数体的内容是将源字符串 s 的内容复制到新分配的内存区域_str中。memcpy函数用于内存块的复制复制从s开始的_size1字节到_str。这里的_size1是因为我们要复制整个字符串包括 null 终止符。 string::string() 以下是函数解释 1.这是string类的默认构造函数。它不接受任何参数并用于创建一个空的 string对象。 2.初始化列表用于在构造函数体执行之前初始化类的成员变量。这里对三个成员变量进行了初始化 2.1初始化_size成员变量为 0表示字符串的长度为零。因为这是一个空字符串所以长度为零。 2.2初始化_capaticy成员变量为 0表示字符串的容量也为零。 2.3使用new char[1]分配了一块大小为 1 字节的动态内存。这块内存用于存储字符串及其终止符\0。 string::string(const string s) 以下是关于函数的解释 这段代码是一个拷贝构造函数用于创建一个string类的新对象它是现有string对象的副本 string::~string() 以下是函数的解释 1.释放_str指针在堆上申请的空间并将_str置为空指针 2.将_size与_capaticy重新置为0 const char* string::c_str()const 以下是函数的解释 1.返回_str所指向的字符串。 char string::operator[](size_t pos) 以下是函数的解释 1.这段代码定义了string类的一个成员函数operator[ ]用于访问字符串中的字符。这个函数是一个重载的下标运算符允许通过下标直接访问字符串中的字符。 2.assert是一个宏用于在调试阶段检查条件是否为真。如果条件不为真程序会中断并输出错误信息。这里检查pos是否在有效范围内如果是则程序继续执行。 3.return _str[pos];如果索引pos合法函数返回_str[pos]。 _str是一个指向字符数组的指针因此_str[pos] 表示数组中第 pos个位置的字符并且返回的是引用所以可以对返回的值进行修改会影响到_str[pos]里的值。 const char string::operator[](size_t pos)const 以下是函数的解释 与上个函数类似但传入的对象以及返回的引用都被const进行修饰此函数可以传const对象因为这是一个权限的平移而上个函数不能传const对象因为会产生权限的放大。并且对返回的引用只能进行读取而不能进行修改。 const size_t string ::size()const 以下是函数的解释 因为_size是成员变量默认是私有的所以不能直接返回并且也不能随意修改通过size() 函数来获取_size的值。 void string::reserve(size_t n) 以下是函数的解释 1.这段代码是一个成员函数reserve用于调整string类的内部字符数组的容量以便容纳至少n个字符的数据; 2.判断n _capaticy检查n是否大于当前已分配的容量_capaticy如果大于就扩容; 3.new char[n 1],在堆上分配一个新的字符数组大小为n1。因为额外的 1 个字符位置用于存储字符串的终止符\0,并temp指针进行接收. 4.memcpy(temp, _str, _size 1)使用memcpy函数将旧字符数组_str的内容包括终止符所以要1复制到新分配的内存temp中 5.释放原_str的内容 6.将_str重新指向新分配内存的指针temp的地址 void string::push_back(char ch) 以下是函数的解释 1.这个push_back函数用于向string对象的末尾添加一个字符并处理容量的扩展。 2.if (_size _capaticy)检查当前字符串的大小是否等于当前容量。如果等于说明字符串需要扩展容量那么则调用创建好的reserve函数进行扩容如果一开始是给空字符串那么_capacity会等于00乘任何数都得0所以要加以进行判断。 3.将字符ch添加到当前字符串的末尾,在赋值后递增_size更新字符串的当前长度; 4.在字符串末尾添加终止符\0标志着字符串的结束 string string:: append(const char*s) 以下是关于函数的解释 1.append函数用于将一个 C 风格的字符串const char* s追加到string对象的末尾 2.strlen(s)计算要追加的字符串s的长度不包括终止符 \0,并且赋值给len 3.检查当前字符串的总长度包括要追加的部分是否超过当前容量,如果超过则调用reserve函数进行扩容 4.拷贝字符串s从原string对象末尾(\0)的位置,并更新_size的值。 string string::operator(const char* s) 以下是关于函数的解释 operatir运算符重载其参数为字符串使用此operatir会复用append函数在原字符串末尾追加字符串s并返回*this(原对象)的引用。 string string::operator(char ch) 以下是关于函数的解释 operatir运算符重载其参数为单个字符,使用此operatir会复用push_backd函数在原字符串末尾追加字符ch并返回*this(原对象)的引用。 string string::insert(size_t pos, const char* s) 以下是关于函数的解释 1.insert函数用于在string对象中的指定位置插入字符串 2.assert检查插入位置pos是否在有效范围内(即不小于 0 且不大于当前字符串的_size 3.strlen(s)计算待插入的字符串s的长度并将其赋值给n 4.更新当前字符串的大小_size,将更新后的_size赋值给len,并判断是否需要扩容 5.end初始化为新的字符串长度_size这是待会插入操作开始前的字符串末尾。 6.while循环从字符串的末尾向插入位置pos移动字符为腾出空间插入新字符串,_str[end n] _str[end]:将字符移动到新的位置并将end--.。注意npos是一个静态成员变量通常定义为size_t(-1)表示无效位置。在这里它的作用是防止end变成负值从而避免无限循环。 7.for循环将待插入的字符串s 的字符逐个复制到目标位置pos开始的位置 8.返回 *this(当前对象)的引用以支持链式调用。 string string::erase(size_t pos, size_t len) 以下是关于函数的介绍 1.erase函数用于从string对象中删除指定位置的字符删除的长度由 len 参数指定(缺省值为npos)。它的实现包括了处理不同情况的逻辑以确保删除操作正确地更新字符串的内容和大小。 2.assert检查pos 是否在有效范围内即 pos 应小于当前字符串的大小_size 3.if语句处理特殊情况 3.1如果len的值是npos(表示删除到字符串的末尾或者pos len超过了 _size则删除从pos位置到字符串末尾的所有字符。 3.2_str[pos] \0;将删除位置设置为字符串结束符\0这会将字符串从pos位置截断,并更新字符串的大小 _size以表示新的字符串长度。 4.else语句处理len小于字符串剩余长度的情况 4.1 int sum 0;初始化一个计数器sum用于记录实际移动的字符数。 4.2 size_t begin pos len;确定开始移动的字符位置。 4.3 while (begin _size)遍历从begin到字符串末尾的所有字符并将它们向前移动到删除的区域(这里字符\0也会向前移动所以不需要再添加\0)以覆盖掉删除的字符。 5._size pos sum;更新字符串的大小_size它应该等于新末尾的位置加上实际移动的字符数。 size_t string::find(char c, size_t pos) const 以下是关于函数的介绍 通过遍历来查找传入的字符c如果找到就返回下标如果没找到则返回npos。 size_t string:: find(const char* s, size_t pos) const 以下是关于函数的介绍 1.运用c语言的库函数strstr查找子串并用char类型的指针temp进行接受 2.如果temp是NULL那么就没找到返回npos如果找到了则将temp的地址-_str的首地址最终会算出子串的第一个字符的下标位置。 string string::substr(size_t pos, size_t len) const 以下是关于函数的介绍 1.substr函数用于生成当前字符串对象的子字符串。它的实现包括对子字符串的提取和处理 2.assert(pos _size);确保pos 在有效范围内。这里_size表示当前字符串的实际大小 3.string temp;创建一个名为 temp的 string 对象用于存储提取的子字符串。 4.if (len npos || pos len _size),如果len是npos表示提取从pos到字符串末尾或者pos len 超过了当前字符串的大小 _size则处理这两种情况 4.1预先为temp对象开好_capaticy个空间,目的是避免频繁的扩容 4.2 for循环从pos位置开始遍历到字符串末尾将每个字符添加到temp字符串中。 5 当len小于等于字符串的剩余长度时提取从pos开始的长度为len的子字符串 5.1为temp字符串扩容,len1是为了确保有足够的空间来存储len个字符和一个\0 5.2 for循环从pos位置开始遍历len个字符,将每个字符添加到 temp 字符串中。
注意这里并不需要专门再结尾添加\0因为temp 会去调用operator的运算符重载而operator里又会调用push_back函数再push_back函数里会对字符末尾进行添加\0的操作 void string::resize(size_t n, char ch) 以下是关于函数的解释 1.resize函数用于调整string对象的大小并且可以用特定的字符填充新增的部分。 2.如果传入的n是小于_size的那么直接将字符串_str[n]替换为\0,并将_size更新为n 3.如果是n大于_size那么先将string对象的内存进行扩容,确保字符串的存储空间足够,然后从_size位置到n 位置填充字符ch。接着在_str[n]插入终结符 \0并更新_size为n。 void string::clear() 以下是关于函数的解释 clear顾名思义是清理的意思那么直接在_str[0]的位置插入终止符\0并把_size更新为0这里没有将_capacity置空是为了怕对象还要进行插入数据防止多次扩容消耗性能。 bool string:: operator(const string s) const 以下是关于函数的解释 .operator函数定义了一个 操作符用于比较当前 string 对象与另一个 string对象的大小。它主要用于ASCII比较即按字母顺序比较 其他的operator比较符重载 string string::operator(string temp) 以下是关于函数的解释 1.接受一个string对象temp的形参 2.在函数体内调用swap(temp)这将当前对象的内容与temp对象的内容交换。 3.交换后当前对象就变成了 temp 的内容temp变成了当前对象的旧内容,并且因为temp是局部参数在函数调用的时候自动进行析构防止了内存泄漏 ostream manbo:: operator(ostream out, const string s) 以下是关于函数的解释 1.operator函数是一个重载的输出流操作符用于将string对象的内容输出到输出流 2.范围for循环auto ch自动推导ch的类型为s中的字符类型循环遍历s中的每一个字符并将其逐个输出到流out中 3.返回流out以支持链式操作。比如outs1s2; istreammanbo:: operator(istream in, string s) 以下是关于函数的解释 1.operator函数是一个重载的输入流操作符用于从输入流读取字符串并将其存储到string对象s中。 2.s.clear();使s变为空字符串以确保读取的内容覆盖之前的内容. 3.char ch;ch in.get();使用in.get()从流中读取一个字符并存储在ch中。 4.while循环跳过开头无用的字符如\0或\n直到读取到第一个有用的字符 5.使用一个字符数组buff作为缓冲区来临时存储字符,i用于确认buff数组的位置。 6.while循环 只要字符不是\0和\n就将字符存入缓冲区buff。缓冲区buff里有 127 个字符时留一个位置给终止符\0将缓冲区内容到s中并重置i。 7.如果i0表示buff里有剩余的字符将这些字符到s对象中 8. 返回流in的引用以支持链式输入操作。比如cins1s2; 测试文件
void test01()
{manbo::string s1;manbo::string s2Hello world;cout s2.c_str() endl;cout s1.c_str() endl;manbo::string const s3 asdddd;
}void test02()
{manbo::string const s2 Hello world;manbo::string::iterator it s2.begin();while (it!s2.end()){cout *it;it;}cout endl;
}void test03()
{manbo::string s2 Hello world;s2.insert(6, ******);cout s2.c_str() endl;s2.erase(0);cout s2.c_str() endl;
}void test04()
{manbo::string s2 Hello world;size_t pos1 s2.find(world);size_t pos2 s2.find(e);cout pos2 endl;
}void test05()
{manbo::string s1 https://www.bilibili.com/video/BV1fW421X7gD/?spm_id_from333.1007.tianma.6-1-19.click;//解析网址分协议 域名 资源size_t pos1 s1.find(://);if (pos1 manbo::string::npos){cout No Find;exit(1);}manbo::string agreement s1.substr(0, pos1);cout 协议: agreement.c_str() endl;size_t pos2 s1.find(/, pos1 3);if (pos2 manbo::string::npos){cout No Find;exit(1);}manbo::string domain s1.substr(pos1 3, pos2 - (pos1 3));cout 域名: domain.c_str() endl;manbo::string resource s1.substr(pos2 1);cout 资源: resource.c_str() endl;
}void test06()
{string s1 hello world;manbo::string s2 hello world;//s1.resize(4,x);//s2.resize(4,x);s1 \0;s1 ******;s2 \0;s2 ******;cout s1 endl;cout s2 endl;manbo::string s3;cin s3;cout s3;cin s3;cout s3;
}void test07()
{manbo::string s1hello;manbo::string s2hello world;cout (s1 s2) endl;cout (s1 s2) endl;cout (s1 s2) endl endl;manbo::string s3 hello world;manbo::string s4 hello;cout (s3 s4) endl;cout (s3 s4) endl;cout (s3 s4) endlendl;manbo::string s5 hello;manbo::string s6 hello;cout (s5 s6) endl;cout (s5 s6) endl;cout (s5 s6) endl endl;
}void test08()
{manbo::string s1 hello;manbo::string s2 hello world;s1 s2;cout s1;}
文章转载自: http://www.morning.tdscl.cn.gov.cn.tdscl.cn http://www.morning.qsy41.cn.gov.cn.qsy41.cn http://www.morning.hwbf.cn.gov.cn.hwbf.cn http://www.morning.24vy.com.gov.cn.24vy.com http://www.morning.nynlf.cn.gov.cn.nynlf.cn http://www.morning.llgpk.cn.gov.cn.llgpk.cn http://www.morning.xnnpy.cn.gov.cn.xnnpy.cn http://www.morning.ranglue.com.gov.cn.ranglue.com http://www.morning.mlpmf.cn.gov.cn.mlpmf.cn http://www.morning.zbmcz.cn.gov.cn.zbmcz.cn http://www.morning.hxwhyjh.com.gov.cn.hxwhyjh.com http://www.morning.pnljy.cn.gov.cn.pnljy.cn http://www.morning.npmpn.cn.gov.cn.npmpn.cn http://www.morning.zdmlt.cn.gov.cn.zdmlt.cn http://www.morning.rmxk.cn.gov.cn.rmxk.cn http://www.morning.ggtkk.cn.gov.cn.ggtkk.cn http://www.morning.ldcsw.cn.gov.cn.ldcsw.cn http://www.morning.wtbzt.cn.gov.cn.wtbzt.cn http://www.morning.nrzbq.cn.gov.cn.nrzbq.cn http://www.morning.bkcnq.cn.gov.cn.bkcnq.cn http://www.morning.jnbsx.cn.gov.cn.jnbsx.cn http://www.morning.fflnw.cn.gov.cn.fflnw.cn http://www.morning.nypsz.cn.gov.cn.nypsz.cn http://www.morning.bpmnl.cn.gov.cn.bpmnl.cn http://www.morning.lbcbq.cn.gov.cn.lbcbq.cn http://www.morning.bnlsd.cn.gov.cn.bnlsd.cn http://www.morning.zpqk.cn.gov.cn.zpqk.cn http://www.morning.jlgjn.cn.gov.cn.jlgjn.cn http://www.morning.rnmdp.cn.gov.cn.rnmdp.cn http://www.morning.smyxl.cn.gov.cn.smyxl.cn http://www.morning.nbqwr.cn.gov.cn.nbqwr.cn http://www.morning.gpryk.cn.gov.cn.gpryk.cn http://www.morning.zzhqs.cn.gov.cn.zzhqs.cn http://www.morning.cwkcq.cn.gov.cn.cwkcq.cn http://www.morning.zxfdq.cn.gov.cn.zxfdq.cn http://www.morning.27asw.cn.gov.cn.27asw.cn http://www.morning.fllfc.cn.gov.cn.fllfc.cn http://www.morning.wcft.cn.gov.cn.wcft.cn http://www.morning.tsycr.cn.gov.cn.tsycr.cn http://www.morning.jxfsm.cn.gov.cn.jxfsm.cn http://www.morning.ycnqk.cn.gov.cn.ycnqk.cn http://www.morning.lrjtx.cn.gov.cn.lrjtx.cn http://www.morning.rwjtf.cn.gov.cn.rwjtf.cn http://www.morning.kfyjh.cn.gov.cn.kfyjh.cn http://www.morning.xqbbc.cn.gov.cn.xqbbc.cn http://www.morning.dbdmr.cn.gov.cn.dbdmr.cn http://www.morning.nspbj.cn.gov.cn.nspbj.cn http://www.morning.ywndg.cn.gov.cn.ywndg.cn http://www.morning.gtjkh.cn.gov.cn.gtjkh.cn http://www.morning.fnssm.cn.gov.cn.fnssm.cn http://www.morning.ngcsh.cn.gov.cn.ngcsh.cn http://www.morning.wkmpx.cn.gov.cn.wkmpx.cn http://www.morning.nlzpj.cn.gov.cn.nlzpj.cn http://www.morning.pwgzh.cn.gov.cn.pwgzh.cn http://www.morning.wztnh.cn.gov.cn.wztnh.cn http://www.morning.jjpk.cn.gov.cn.jjpk.cn http://www.morning.kqzxk.cn.gov.cn.kqzxk.cn http://www.morning.bzkgn.cn.gov.cn.bzkgn.cn http://www.morning.xzgbj.cn.gov.cn.xzgbj.cn http://www.morning.tgydf.cn.gov.cn.tgydf.cn http://www.morning.ljzss.cn.gov.cn.ljzss.cn http://www.morning.pqxjq.cn.gov.cn.pqxjq.cn http://www.morning.bpkqd.cn.gov.cn.bpkqd.cn http://www.morning.wrqw.cn.gov.cn.wrqw.cn http://www.morning.pwlxy.cn.gov.cn.pwlxy.cn http://www.morning.prhqn.cn.gov.cn.prhqn.cn http://www.morning.dqkrf.cn.gov.cn.dqkrf.cn http://www.morning.zbkwj.cn.gov.cn.zbkwj.cn http://www.morning.gllhx.cn.gov.cn.gllhx.cn http://www.morning.rjnx.cn.gov.cn.rjnx.cn http://www.morning.zffps.cn.gov.cn.zffps.cn http://www.morning.wrtsm.cn.gov.cn.wrtsm.cn http://www.morning.cfnht.cn.gov.cn.cfnht.cn http://www.morning.wknjy.cn.gov.cn.wknjy.cn http://www.morning.xqgfy.cn.gov.cn.xqgfy.cn http://www.morning.bxqtq.cn.gov.cn.bxqtq.cn http://www.morning.trrrm.cn.gov.cn.trrrm.cn http://www.morning.skbbt.cn.gov.cn.skbbt.cn http://www.morning.pqryw.cn.gov.cn.pqryw.cn http://www.morning.blfgh.cn.gov.cn.blfgh.cn