【C++】string类的使用
目录
一、标准库中的string类
二、string类的常用接口
1、string类对象的常见构造
2、string类对象的容量操作
2.1、size 与 length
2.2、capacity 与 reserve
2.3、resize
2.4、总结
3、string类对象的访问及遍历操作
3.1、operator[] 与 at
3.2、begin + end
3.3、rbegin + rend
3.4、 const类型迭代器
3.5、范围for
4. string类对象的修改操作
4.1、push_back、append、operator+=
4.2、insert 与 erase
4.3、find 与 replace
4.4、substr 与 rfind
4.5、c_str
4.6、find_first_of 与 find_last_of
5、string类非成员函数
5.1、getline
一、标准库中的string类
string类是由模板 basic_string 显示实例化为 char 类型得到的类,并用关键字 typedef 命名为 string 。
当模板参数是 char 时,类名为 string ,与之相对的,还有其他各种各样由模板 basic_string 显示实例化的到的类名,比如:wstring、u16string、u32string等
wstring 类管理的是 wchar_t 类型的字符,一个字符占据 2 个字节。
u16string 类管理的是 char16_t 类型的字符,一个字符占据 2 个字节。
u32string 类管理的是 char32_t 类型的字符,一个字符占据 4 个字节。
之所以要区分出这么多字符类,是为了满足各种各样不同的需求,比如编码的需求。
以 ascll 码为例,ascll码的出现是为了更好的表示英文,算上26个字母、10个数字以及各种各样的符号、控制字符等等,只需要 128 个字符的映射表就能满足几乎所有的表示需求。
但是对于中文、甚至是更加复杂的文字而言,128个字符的映射表就已经没有办法满足需求了,就需要更多字符的映射表,自然也需要占据更多字节大小的空间。
为了更好的满足这一需求,就出现了另一个编码规则:Unicode,即统一码。统一码又分为 3 种,分别为 UTF-8、UTF-16、UTF-32。
UTF-8兼容ascll码,对不同范围的字符使用不同长度的编码,也是我们最常用的编码方式。
对于0x00-0x7F之间的字符,UTF-8编码与ascll编码完全相同。UTF-8编码的最大长度是4个字节。从上表可以看出,4字节模板有21个x,即可以容纳21位二进制数字。统一码的最大码位0x10FFFF也只有21位。UTF-8 编码以二进制数字的前缀来区分一个字符占据几个字节。
其中类 string 所对应的编码方式就是 UFT-8 。
我们来举个例子具体说明一下:
str1 中存储的是英文字母,使用 ascll 码即可表示(一个字符占据一个字节),例如 'h' 的值为十进制 104 ,换算到八位二进制为 01101000 ,前缀为零。
str2 中存储的是中文字符,一个字符占据两个字节,所以这两个字节的二进制数前缀分别为 110 与 10。转换成十进制表现为两个负数。两个中文字符就是四个字节,加上最后的 '\0' 为五个字节大小。
通过更改中文字符的数值,我们可以观察到中文字符编码的规律是把同音字编在一起的:
二、string类的常用接口
1、string类对象的常见构造
(constructor)函数名称 | 功能说明 |
string() | 构造空的string类对象,即空字符串 |
string(const char* s) | 用C-string来构造string类对象 |
string(size_t n, char c) | string类对象中包含n个字符c |
string(const string& s) | 拷贝构造函数 |
string (const string& str, size_t pos, size_t len = npos) | 拷贝从字符串第 pos 个字符开始向后的 npos 个字符 |
例如:
对于 string (const string& str, size_t pos, size_t len = npos) ,库中提供了一些额外的解释,如果 npos 的大小超出了字符串的有效长度范围,就自动取到字符串中最后一个有效字符为止。如果没有指定 npos 的值,就使用缺省参数 -1 ,由于 size_t 是无符号整型,所以 -1 实际上是二进制的全一,即最大的整型数值 2^32 - 1 。
2、string类对象的容量操作
函数名称 | 功能说明 |
size(重点) | 返回字符串有效字符长度 |
length | 返回字符串有效字符长度 |
capacity | 返回空间总大小 |
empty (重点) | 检测字符串是否为空串,是返回true,否则返回false |
clear (重点) | 清空有效字符 |
reserve (重点) | 为字符串预留空间** |
resize (重点) | 将有效字符的个数改成n个,多出的空间用字符c填充 |
2.1、size 与 length
size 与 length 都是返回字符串的有效字符长度,用法如下:
功能完全相同,只是为了名字与 stl 中其他模板的名称保持一致,就增加了一个 size ,除了名字不同外,没有区别。
2.2、capacity 与 reserve
capacity 返回空间总大小,用于观察开辟空间的情况:
当不断向string对象 s 中尾插字符时,会导致 s 不断的扩容,可以发现除了第一次扩容外,其他扩容后的大小都是上一次的 1.5 倍。
string 对象第一次扩容的规则大致如下:
类string中有一个容量为 16 个字符的数组 buf ,如果对象中存储的字符数量小于等于 16 个,就会把字符存入数组 buf 中,不使用指针 _ptr 。如果对象中存储的字符数量大于 16 个,就会使用指针 _ptr 来开辟空间,第一次直接开辟 32 个字符的空间,并把字符存放在新开辟的空间中, buf 不再使用。之后每次开辟的空间大小是开辟之前大小的 1.5 倍。
这种规则只适用于VS编译器,不同的编译器有不同的扩容规则。
为了防止编译器不断的给 string 对象扩容空间,造成资源的浪费,我们可以使用 reserve 直接给对象预留一定大小的空间:
其中因为一些内存对齐等原因,实际内存空间与我们设定的有一些出入,但一定不会比我们设置的小。
2.3、resize
resize 将有效字符的个数改成 n 个,多出的空间用字符c填充。 resize 可以扩容空间,并进行初始值填充:
可以看到 resize 与 reserve 不同。使用 resize 进行扩容的时候,也进行了字符填充,使对象的有效字符长度也发生了变化。
在vs编译器中,默认填充的字符是 '\0' 。
我们也可以指定填充的字符,写成如下形式:
如果指定的 n 值比 size 小,则会删除数据,保留前 n 个:
size 变为 5 , capacity 的值不变。
2.4、总结
- size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()。
- clear()只是将string中有效字符清空,不改变底层空间大小。
- resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。
- reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserver不会改变容量大小。
3、string类对象的访问及遍历操作
函数名称 | 功能说明 |
operator[] | 返回pos位置的字符,const string类对象调用 |
begin+ end | begin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭 代器 |
rbegin + rend | begin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭 代器 |
范围for | C++11支持更简洁的范围for的新遍历方式 |
3.1、operator[] 与 at
operator[] 返回pos位置的字符,是一个运算符重载,关于运算符重载的内容,在《类和对象(二)》里有过详细的说明。
at 的作用与 [] 类似,都是获取指定下标的数据,只不过在越界的处理方面有些不同。如果 [] 中的下标越界,程序会直接发生断言错误,终止程序,而如果 at 指向的下标越界,则会进行抛异常。
3.2、begin + end
我们想要打印一个数组,除了使用运算符重载 [] 外,还可以使用 begin 与 end 获取迭代器。具体用法如下:
关于迭代器,大家暂时可以先理解为指针, begin 是第一个位置的指针, end 是最后一个位置的下一个位置的指针。
3.3、rbegin + rend
rbegin 与 rend 获取的是反向迭代器,目前阶段同样可以先把他们看作指针,其中 rbegin 指向最后一个数据的位置, rend 指向第一个位置的前一个位置:
用法如下:
3.4、 const类型迭代器
当使用 const 类型来接收string类对象时,如果直接使用关键字 interator 来定义迭代器变量,编译器会报错。
所以为了保证权限不被放大,需要使用关键字 const_iterator 来定义迭代器变量:
3.5、范围for
打印一个数组,还有另一种方法,就是使用 范围for ,具体用法如下:
实际上,范围for的底层就是使用迭代器来实现的。
4. string类对象的修改操作
函数名称 | 功能说明 |
push_back | 在字符串后尾插字符c |
append | 在字符串后追加一个字符串 |
operator+= (重点) | 在字符串后追加字符串str |
c_str(重点) | 返回C格式字符串 |
find(重点) | 从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置 |
replace | 替换字符串pos位置,len长度的字符 |
rfind | 从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置 |
substr | 在str中从pos位置开始,截取n个字符,然后将其返回 |
insert | 在str中插入字符 |
erase | 在str中删除字符 |
find_first_of | 找到其中任意一个字符,并返回其位置 |
find_last_of |
4.1、push_back、append、operator+=
push_back 在字符串尾部插入字符,具体用法如下:
append 在字符串尾部插入字符串,具体用法如下:
相比较于以上两种接口,最简单且最常用的其实是 operator+= ,具体用法如下:
4.2、insert 与 erase
insert :在字符串的 pos 位置插入字符串或者 n 个字符。
比如在字符串 "world" 的第 0 个位置插入字符串 "hello" :
在字符串 "helloworld" 第 5 个位置插入 1 个字符 ' ' :
erase :在字符串的 pos 位置删除 n 个字符。
例如,在字符串 "hello world" 的第 6 个位置删除 1 个字符:
如果指定的 n 超出了字符串的有效范围,或者不指定 n 的值,就删除到字符串最后的位置。
注意: insert 与 erase 不推荐经常使用,因为他们可能都要挪动数据,效率低下。
4.3、find 与 replace
find :从字符串的 pos 位置向后寻找指定字符,返回该字符在字符串中的位置,如果没有指定 pos 的值,就使用缺省参数 0 。如果字符串中没有找到指定字符,就返回 npos ,即无符号整型 -1 。
例如,找到字符串 "hello world" 中 ' ' 的位置:
找到字符串 "hello world i love you" 中第二个 ' ' 的位置:
replace :替换字符串 pos 位置, len 长度的字符。
例如,把字符串 "hello world i love you" 中所有的 ' ' 都替换为 "%20" :
这样每次使用 replace 来替换字符,都会扩容空间,为了提高效率,我们可以使用 reserve 来提前开辟空间:
4.4、substr 与 rfind
substr :在str中从 pos 位置开始,截取 n 个字符,然后将其返回。
例如:打印字符串 "string.cpp" 的后缀:
如果我们不指定 n 的值,就使用缺省参数 npos ,即无符号整型 -1 。 不指定 pos 的值,就是用缺省参数 0 :
不过也有时,文件的名字中存在多个字符 '.' , 为了寻找文件真正的后缀,我们需要找到最后一个 '.' 的位置。可以使用 rfind :从字符串pos位置开始往前找指定字符,返回该字符所在的位置:
4.5、c_str
c_str 返回C格式字符串。
打印字符串有如下两种方式:
其中第一种,s 是自定义类型, "<<" 是自定义类型重载的流插入。第二种 s.c_str() 返回的是C格式字符串的指针,类型为 char* , "<<" 是库里面的流插入。如果把 s.c_str() 返回的指针强转成其他类型,就会打印出指针,而不是字符串:
如果把字符串进行以下处理后,这两种打印方式得到的结果是不同的:
可知,如果我们使用流插入来打印string对象,会以 size 的大小来打印,不会关注 '\0' 。而使用流插入来打印 char* 类型的指针,就会打印到 '\0' 后结束。
4.6、find_first_of 与 find_last_of
find_first_of :在字符串中,从前往后找到其中任意一个字符,并返回其位置。
例如,把一段字符串中所有的 'a'、'b'、'c'、'd' 都替换为 '*' 。
find_last_of :在字符串中,从后往前找到其中任意一个字符,并返回其位置。
5、string类非成员函数
函数 | 功能说明 |
operator+ | 尽量少用,因为传值返回,导致深拷贝效率低 |
operator>> | 输入运算符重载 |
operator<< | 输出运算符重载 |
getline (重点) | 获取一行字符串 |
relational operators | 大小比较 |
5.1、getline
当我们使用 cin 来提取字符串时,字符串中不能含有空格,因为 cin 在遇到空格、'\n' 等字符时,会默认提取结束。
为了解决这个问题,我们可以使用 getline :
int main()
{string str;//cin >> str;getline(cin, str);return 0;
}
关于string类的使用相关内容就讲到这里,希望同学们多多支持,如果有不对的地方欢迎大佬指正,谢谢!
相关文章:
【C++】string类的使用
目录 一、标准库中的string类 二、string类的常用接口 1、string类对象的常见构造 2、string类对象的容量操作 2.1、size 与 length 2.2、capacity 与 reserve 2.3、resize 2.4、总结 3、string类对象的访问及遍历操作 3.1、operator[] 与 at 3.2、begin end 3.3、…...
微服务架构简介
微服务 软件架构是一个包含各种组织的系统组织,这些组件包括 Web服务器, 应用服务器, 数据库,存储, 通讯层), 它们彼此或和环境存在关系。系统架构的目标是解决利益相关者的关注点。 image Conway’s law: Organizations which design systems[...] are constrained…...
【Spring源码】AOP的开端:核心对象创建的准备工作
AOP的核心成员是如何被被加载的?本篇我们主要分析使用xml的逻辑,如果使用注解,增加注解处理类即可(ConfigurationClassPostProcessor)拿之前分析循环的时候举的例子🌰,它的日志切面就是通过xml进…...
新号涨粉22w,搞笑博主再次爆火,小红书近期创作趋势是什么?
2月借势元宵、情人节,小红书平台又涌现出哪些黑马博主?品牌在投放种草方面有何亮眼表现?为洞察小红书平台的内容创作趋势及品牌营销策略,新红推出2月月度榜单,从创作者及品牌两方面入手,解析月榜数据&#…...
【C++】30h速成C++从入门到精通(内存管理、函数/类模板)
C内存分布我们先来看一下下面的一段代码相关问题int globalVar 1; static int staticGlobalVar 1; void Test() {static int staticVar 1;int localVar 1;int num1[10] {1, 2, 3, 4};char char2[] "abcd";char* pChar3 "abcd";int* ptr1 (int*)mal…...
自动驾驶决策概况
文章目录1. 第一章行为决策在自动驾驶系统架构中的位置2. 行为决策算法的种类2.1 基于规则的决策算法2.1.1 决策树2.1.2 有限状态机(FSM)2.1.3 基于本体论(Ontologies-based)2.2 基于统计的决策算法2.2.1 贝叶斯网络(B…...
金山轻维表项目进展自动通知
项目经理作为项目全局把控者,经常要和时间“赛跑”。需要实时了解到目前进展如何,跟进人是那些?哪些事项还未完成?项目整体会不会逾期?特别是在一些大型公司中,优秀的项目经理已经学会使用金山轻维表做项目…...
基于上下文分析的 Python 实时 API 推荐
原文来自微信公众号“编程语言Lab”:基于上下文分析的 Python 实时 API 推荐 搜索关注 “编程语言Lab”公众号(HW-PLLab)获取更多技术内容! 欢迎加入 编程语言社区 SIG-程序分析 参与交流讨论(加入方式:添加…...
软件测试-接口测试-代码实现接口测试
文章目录 1.request1.1 request介绍1.2 发送get请求1.3 发送set请求1.4 其他请求方式1.5 传递url参数1.6 响应内容解析1.7 cookie1.8 设置session2.集成UnitTest2.1 接口测试框架开发2.2 案例:使用TPShop项目完成对登录功能的接口测试1.request 1.1 request介绍 概念 基于py…...
中村成洋《垃圾回收的算法与实现》PDF 读书笔记
观前提醒 为了能够锻炼自己,我会查阅大量外文不停的修改内容,少部分会提示成中文。 可能有误,请见谅 提示:若是觉得阅读困难,可以看如下内容 脚本之家可获取,若失效可私信浏览器的沙拉查词扩展…...
docker 网络模式
docker 网络模式主要分为四种,可以通过docker network ls 查看 ~$ docker network ls NETWORK ID NAME DRIVER SCOPE a51d97d72f10 bridge br…...
数据库开发(一文概括mysql基本知识)
Mysql 是最流行的关系型数据库管理系统,在 WEB 应用方面 MySQL 是最好的 关系型数据库(Relational Database Management System:关系数据库管理系统)应用软件之一。mysql在问开发中,几乎必不可少,因为其他的可能是要收费的&#x…...
【JVM】详解Java内存区域和分配
这里写目录标题一、前言二、运行时数据分区2.1程序计数器(PC)2.2 Java虚拟机栈2.3 本地方法栈2.4 Java堆2.5 方法区2.5.1 运行时常量池2.6 直接内存三、HotSpot虚拟机对象探秘3.1 对象的创建3.2 对象的内存布局3.3 对象的访问定位一、前言 C/C需要自行回收和释放已经没用的对象…...
JAVA开发(史上最完整追本溯源JAVA历史、发展和学习)
(第二次世界大战1931-1945) 世界上最先进的技术往往是由于战争催生,在第二次世界大战中除了飞机,坦克和大炮的武器较量外,在隐秘战线的情报工作其实更为重要,在军队将领来往的电报中,为了防止军事情报的泄漏ÿ…...
Qt 防止程序退出
文章目录摘要QWidgetQML方法 1方法 2关键字: Qt、 eventFilter、 Close、 键盘、 任务管理器摘要 今天要聊得内容还是怎么防止别人关闭我的程序,之前都是在win下面,一般都是用过钩子连捕获键盘事件,完了吧对应的事件忽略&#x…...
【校验码 - 循环冗余校验码CRC】
水善利万物而不争,处众人之所恶,故几于道💦 目录 循环冗余校验码 1.多项式 2.CRC编码的组成 3.校验码的生成 4.例题: 循环冗余校验码 广泛地在网络通信及磁盘存储时采用。 1.多项式 在循环冗余校验(CRC)码中,无一例…...
【Rust】一文讲透Rust中的PartialEq和Eq
前言 本文将围绕对象:PartialEq和Eq,以及PartialOrd和Ord,即四个Rust中重点的Compare Trait进行讨论并解释其中的细节,内容涵盖理论以及代码实现。 在正式介绍PartialEq和Eq、以及PartialOrd和Ord之前,本文会首先介绍…...
Vulnhub靶场----9、DC-9
文章目录一、环境搭建二、渗透流程三、思路总结一、环境搭建 DC-9下载地址:https://download.vulnhub.com/dc/DC-9.zip kali:192.168.144.148 DC-9:192.168.144.158 二、渗透流程 1、信息收集nmap -T5 -A -p- -sV -sT 192.168.144.158思路&am…...
使用Containerd搭建K8s集群【v1.25】
[toc] 一、安装要求 在开始之前,部署Kubernetes集群机器需要满足以下几个条件: 一台或多台机器,操作系统 CentOS7.x-86_x64硬件配置:2GB或更多RAM,2个CPU或更多CPU,硬盘30GB或更多集群中所有机器之间网络互通可以访问外网,需要拉取镜像禁止swap分区二、准备环境 角色IP…...
NMT - 构建双语概率词典(Probabilistic dictionaries)
文章目录一、安装依赖包mosesdecoder安装 mgiza二、数据预处理三、训练本文参考:How to train your Bicleaner https://github.com/bitextor/bicleaner/wiki/How-to-train-your-Bicleaner 一、安装依赖包 这个过程主要依赖于 mosesdecodermgiza mosesdecoder git…...
《ChatGPT是怎样炼成的》
ChatGPT 在全世界范围内风靡一时,我现在每天都会使用 ChatGPT 帮我回答几个问题,甚至有的时候在一天内我和它对话的时间比和正常人类对话还要多,因为它确实“法力无边,功能强大”。 ChatGPT 可以帮助我解读程序,做翻译…...
Streaming System是第一章翻译
GIthub链接,欢迎志同道合的小伙伴一起翻译 Chapter 1.Streaming101 如今,流数据处理在大数据中是非常重要的,其主要原因是: 企业渴望对他们的数据有更及时的了解,而转换到流处理是实现更低延迟的一个好方法…...
abap MODIFY常用语法解析
MODIFY 是既可以操作数据又可以操作内表的一个语法, 实现的逻辑都一样. 如果你内表或数据库中存在该行数据会对该行数据进行更新. 如果不存在,就会插入数据. , 1.如果it_tab是带有标题行的内表,是可以忽略FROM wa_tab工作区的 MODIFY it_tab .2.把工作区wa_tab中的数据更新…...
[媒体分流直播]媒体直播和传统直播的区别,以及媒体直播的特点
传媒如春雨,润物细无声,大家好,我是51媒体网胡老师。 直播毋庸置疑已经融入到了我们生活的方方面面,小到才艺,游戏,大到政策的发布,许多企业和机构也越来越重视直播,那么一场活动怎…...
打地鼠游戏-第14届蓝桥杯STEMA测评Scratch真题精选
[导读]:超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成,后续会不定期解读蓝桥杯真题,这是Scratch蓝桥杯真题解析第102讲。 蓝桥杯选拔赛现已更名为STEMA,即STEM 能力测试,是蓝桥杯大赛组委会与美国普林斯顿多…...
链表经典刷题--快慢指针与双指针
本篇总结链表解题思路----快慢指针,其实也就是双指针,这个快慢并不单纯指“快慢”,它更多的可以表示,速度快慢,距离长度,时间大小等等,用法很有趣也很独特,理解它的思想,…...
【Java集合框架】篇四:Set接口
1. Set及主要实现类特点 Set:无序、不可重复(去重)、存储value HashSet:底层使用HashMap,即使用 数组单项链表红黑树 结构进行存储。(jkd8中) LinkedHashSet:是HashSet的子类&…...
Python 数据库连接 + 创建库表+ 插入【内含代码实例】
人生苦短 我用python Python其他实用资料:点击此处跳转文末名片获取 数据库连接 连接数据库前,请先确认以下事项: 您已经创建了数据库 TESTDB.在TESTDB数据库中您已经创建了表 EMPLOYEEEMPLOYEE表字段为 FIRST_NAME, LAST_NAME, AGE, SEX 和 INCOME。连…...
DSS 部署环境需求清单
文章目录 DSS系统需求项目地址计算资源计算基准:计算引擎程序硬件需求表 :DSS计算及存储资源需求计算资源计算基准:计算程序硬件需求表:DSS系统需求 项目地址 https://github.com/WeBankFinTech/DataSphereStudio 计算资源计算基准: 1.日活用户10万。 2.单用户单日总…...
Python的面向对象,详细讲解Python之用处等基本常识
目录 Python 面向对象 面向对象技术简介 创建类 实例 实例 self代表类的实例,而非类 实例 创建实例对象 访问属性 实例 Python内置类属性 实例 python对象销毁(垃圾回收) 实例 实例 类的继承 实例 方法重写 实例 基础重载方法 运算符重载 实例…...
提供服务好的网站归档系统/百度网络优化推广公司
类似于文本框里面hint文字在初始化的时候显示或者隐藏的操作,就要用到setOnFocusChangeListener的 首先我觉得不是太必要~ 毕竟当你输入东西时,默认文字自然会消失 当然如果你执意要这样做 你可以在onCreate方法中通过findViewById找到该Edi…...
做的好的网站有哪些/怎么在百度上设置自己的门店
-- 根据表名找表信息 -- Sql Server select * from sysobjects where xtypeU and name 表名; -- Oracle select table_name,tablespace_name,temporary from user_tables where table_nameTEST_TEMP; --(表名变量值必须大写) -- 根据字段找对应表名 -- Sql Server select a…...
公司建网站会计分录/营销软件商城
linux删除用户的方法:首先进入系统创建一个用户;然后对该用户一些信息目录查看;最后正确删除用户,代码为【[rootlocalhost /]# userdel -r haha】。本教程操作环境:linux5.9.8,DELL G3电脑。linux删除用户的…...
实训做网站收获/正规接单赚佣金的平台
芯片设计进阶之路——门控时钟低功耗深入理解(二)------------------------------------------版权声明:本文作者: 烓围玮未。 主要从事ISP/MIPI/SOC/车规芯片设计首发于知乎专栏:芯片设计进阶之路微信公众号ÿ…...
网站排队队列怎么做/百度app下载官方
分享一个换肤解决方案参考文章: (1)分享一个换肤解决方案 (2)https://www.cnblogs.com/xie-zhonglai/p/skins.html 备忘一下。...
将网站制作成app/比较好的网络推广平台
https://blog.csdn.net/ylforever/article/details/79191182 转载于:https://www.cnblogs.com/2016-cxp/p/10915529.html...