C++获取含有中文字符的string长度
:前言
造车轮的时候要用到中文字符串的长度辨别,发现char的识别不准,进行了一番研究。
> 开始研究
在Windows下,中文字符在C++中的内存占用为2字节,此时采用字符串长度获取函数得到的结果会将一个中文字符识别为两个长度:
#include <stdio.h>
#include <string>
using namespace std;//string在std命名空间中
int main()
{
string str = "abc中文def";
printf("字符串为:%s\n", str.data());//data()函数回传字符串的指针,与c_str()相同
int len;
char str1[50];
strcpy(str1, str.data());//赋值
len = strlen(str1);
printf("字符串的长度为(%d)\n", len);
//使用strlen函数获取长度
string str2 = str;//也可以用string str2.assign(str),这是string的赋值函数,不过和=没区别
len = str2.length();//也可以用len = str2.size();
printf("字符串的长度为(%d)\n", len);
//使用string类的长度获取函数length()
system("pause");
}
点击查看输出
字符串为:abc中文def
字符串的长度为(10)
字符串的长度为(10)
请按任意键继续. . .
而实际上,字符串的长度为8,并非上述方法的结果10。那么,如何获取真正的长度呢?
>> 上手尝试
其实,我们不妨试试中文字符的值:
char a = '中';
char b = '文';
char c = '字';
char d = '符';
printf("字符‘中’在编码中的值为%d\n",(int)a);
printf("字符‘文’在编码中的值为%d\n",(int)b);
printf("字符‘字’在编码中的值为%d\n",(int)c);
printf("字符‘符’在编码中的值为%d\n",(int)d);
system("pause");
点击查看输出
字符‘中’在编码中的值为-48
字符‘文’在编码中的值为-60
字符‘字’在编码中的值为-42
字符‘符’在编码中的值为-5
请按任意键继续. . .
试试其他中文字符,也都是负数。
>> 总结归纳
依据这一点,我们便可以做出一个获取含有中文的字符串长度的函数:
string版:
int getLength_str(string str)
{
int count = 0;
for (int i = 0; str[i]; i++)
{
if (str[i] < 0) i++;
//负数说明该字符为中文字符,占用两个字节,跳过后一个字节(i++),不进行统计
count++;
}
return count;
}
char版: 虽然char数组也可以传入上面的函数,不过为了避免某些奇葩编译器,还是再写了一个函数,即拷即用:
int getLength_char(char str[])
{
int count = 0;
for (int i = 0; str[i]; i++)
{
if (str[i] < 0) i++;
count++;
}
return count;
}
不过,char版不可以传string。
>> 试验验证
用前面的示例验证:
点击查看代码
#include <stdio.h>
#include <string>
using namespace std;
int getLength_str(string str)
{
int count = 0;
for (int i = 0; str[i]; i++)
{
if (str[i] < 0) i++;
//负数说明该字符为中文字符,占用两个字节,跳过后一个字节(i++),不进行统计
count++;
}
return count;
}
int getLength_char(char str[])
{
int count = 0;
for (int i = 0; str[i]; i++)
{
if (str[i] < 0) i++;
count++;
}
return count;
}
int main()
{
string str = "abc中文def";
printf("字符串为:%s\n", str.data());//data()函数回传字符串的指针,与c_str()相同
int len;
char str1[50];
strcpy(str1, str.data());//赋值
len = strlen(str1);
printf("字符串的长度为(%d)\n", len);
//使用strlen函数获取长度
len = getLength_char(str1);//len = getLength_str(str1);
printf("字符串的长度为[%d]\n", len);
//用上面的函数获取含有中文字符的字符串的真正长度
string str2 = str;//也可以用string str2.assign(str),这是string的赋值函数,不过和=没区别
len = str2.length();//也可以用len = str2.size();
printf("字符串的长度为(%d)\n", len);
//使用string类的长度获取函数length()
len = getLength_str(str2);
printf("字符串的长度为[%d]\n", len);
//用上面的函数获取含有中文字符的字符串的真正长度
system("pause");
}
点击查看输出
字符串为:abc中文def
字符串的长度为(10)
字符串的长度为[8]
字符串的长度为(10)
字符串的长度为[8]
请按任意键继续. . .
这个函数也可以获取没有中文字符的字符串长度.
总结
通过对中文字符数值的输出,从而找到char数组对中文字符串的长度处理解决方法。
当然处理中文字符串最好的方法是转换成宽字节,但会比较麻烦。
另外,新版的C++20string好像已经解决了这个长度问题。这篇文是之前在CSDN写的,当时是不可以的。
另:
字符串转宽字节后,采用wcslen(wchar_t*)方法可以准确的读出宽字节字符串的字符数(毕竟宽字节就是为了这事专门设计的)
The End
Yuito 2023
C++获取含有中文字符的string长度的更多相关文章
- Tomcat 中get请求中含有中文字符时乱码的处理
Tomcat 中get请求中含有中文字符时乱码的处理
- jQuery判断字符串是否含有中文字符
//判断字符串是不是中文String.prototype.isChinese = function () { var reg = /[^\x00-\xff]/ig;//判断是否存在中文和全角字符 ...
- CP策略含有中文字符提交失败故障解决
硬件平台:CP5600 系统版本:R80.10 补丁版本:TAKE103 故障现象:提交新增策略失败,日志显示 if the problem persists contact Checkpoint S ...
- perl处理含有中文字符的json编码
例子:1. 有php的 json函数生成的中文串 [root@tts177:/tmp]$/opt/php/bin/php -r 'echo json_encode(Array("a" ...
- Servlet & JSP - 中文字符问题
Servlet 中的中文字符 来自 URL 参数部分的中文字符 Tomcat 默认接收数据的编码是 ISO-8859-1.所以当请求 URL 的参数部分含有中文字符,需要转换字符的编码. Enumer ...
- SpringMVC项目中中文字符乱码问题及解决办法总结(非专业最优解决办法) -- ajax传值乱码; request.getParameter()乱码;
情况一: ajax中传值时是乱码(后台可以获取到中文字符,但用@ResponseBody返回时前台为乱码) 情况二: Controller 中 request.getParameter()获取到的是乱 ...
- [python]有中文字符程序异常的解决方案
一. 含有中文字符无法运行 在python3中用的是Unicode编码,Unicode号称万国码,可以向所有的编码进行兼容.不会出现这种问题. Python2中使用的是ASCII编码,会出现这种问题. ...
- 转义URL 含有中文和特殊符号
方法1: //这个方法被废弃了 NSString *urlString = @"https://www.cnblogs.com/huaida/#/程序员"; NSString* e ...
- java String长度与varchar长度匹配理解(字符和字节长度理解)
java String长度与varchar长度匹配理解(字符和字节长度理解) string中的length()长度,返回的是char的数量,每个char可以存储世界上任何类型的文字和字符,一个char ...
- URL query string中文字符问题
如果URL的query string中包含中文字符,在不做特殊处理的情况下通过 request.getParameter 方法是获取不到正确的信息的,这是由于下面的两个机制造成的 浏览器会自动对URL ...
随机推荐
- 鼠标悬浮上去显示小手CSS
鼠标悬浮上去显示小手CSS只需要添加一句css代码即可 cursor:pointer;
- Java多线程(5):CAS
您好,我是湘王,这是我的博客园,欢迎您来,欢迎您再来- 在JDK1.5之前,Java的多线程都是靠synchronized来保证同步的,这会引起很多性能问题,例如死锁.但随着Java的不断完善,JNI ...
- JS中对DOM元素的操作
https://www.runoob.com/jquery/jquery-ref-html.html 1.each 遍历 //遍历所有class为checksingle的DOM元素 $(" ...
- scrapy 解析xml格式的数据
XMLFeedSpider 主要用于 解析 xml格式的数据 创建一个scrapy 项目文件 scrapy startproject xxx 创建一个spider scrapy genspider - ...
- JS 学习笔记(二)Ajax的简单使用
使用Ajax访问本地TXT文件 ajax.js // 创建请求对象 var ajax = new XMLHttpRequest(); // 建立连接 ajax.open('get', 'test.tx ...
- vulnhub靶场之Beelzebub
准备: 攻击机:虚拟机kali.本机win10. 靶机:Beelzebub: 1,网段地址我这里设置的桥接,所以与本机电脑在同一网段,下载地址:https://download.vulnhub.com ...
- SketchUp2020免费中文完整版官网2021教程模型库下载
SketchUp2022 WIN10 64位安装步骤: 1.先使用"百度网盘客户端"下载SU22_CN_x64安装包到电脑磁盘里,并鼠标右击进行解压缩,然后找到SketchUpPr ...
- 图解ReentrantLock底层公平锁和非公平锁实现原理
在面试或者日常开发当中,经常会遇到公平锁和非公平锁的概念. 两者最大的区别如下 1️⃣ 公平锁:N个线程去申请锁时,会按照先后顺序进入一个队列当中去排队,依次按照先后顺序获取锁.就像下图描述的上厕所的 ...
- PGL图学习之图神经网络GNN模型GCN、GAT[系列六]
PGL图学习之图神经网络GNN模型GCN.GAT[系列六] 项目链接:一键fork直接跑程序 https://aistudio.baidu.com/aistudio/projectdetail/505 ...
- javaSE--核心之一:IO流
Java IO流框架结构: IO的主要内容包括输入.输出两种IO流,这两种流中又分为字节流和字符流,字节流是以字节为单位来处理输入.输出流,而字符流是以字符为单位来处理输入.输出流. InputStr ...