当前位置: 首页 > news >正文

C++中常见的字符判断与处理方法

文章目录

  • 前言
  • ASCII 码
  • 判断字符范围的函数
    • C 语言
    • C++
  • 字符判断技巧
    • 判断两个字符互为大小写
    • 哨兵的使用
  • 总结

前言

字符串处理是编程世界中一项基础技能,特别是对于C/C++的程序员们,远没有那么多华丽的工具可以使用,大多数时候都需要一个个字符来判断和处理,甚至对于C语言来说都没有字符串类型,字符数组是其常见的等价结构,所以稳扎稳打的基本功尤其重要。

对于C++而言,确实有string这个字符串类型,在使用的时候有一些技巧和函数可以使用,比C语言要方便许多了,只是有些时候我们并不知道可以这样用,有时一些很朴素的写法会让程序更加简洁,而一些技巧的表达当明白之后也会感叹自己曾经的无知。

ASCII 码

作为字符编码的基础,ASCII码是需要先弄明白的,即使不能把所有的ASCII码对应的字符都记住,也要把常见的字母、数字、特殊字符记住,这样在处理字符问题时可以得心应手,常见的ASCII码对照表如下:

ASCII

其中需要注意的知识点:

  • 前32个为非打印控制字符,后面的字符为打印字符
  • 数字字符 '0'-'9' 对应的ASCII码范围是48-57
  • 大写字母 'A'-'Z' 对应的ASCII码范围是65-90
  • 小写字母 'a'-'z' 对应的ASCII码范围是97-122
  • NULL 对应ASCII码0,回车的ASCII码是13,换行的ASCII码是10

仔细观察这个ASCII表你会发现很多“秘密”,比如 windows 中的文件放到 linux 上打开时常常显示许多的 ^M,其实这就是\r 的表现,因为在 windows 上用 \r\n 表示换行,而 linux 上使用 \n 换行,那么多余的 \r 在 linux 上就会显示成 ^M

再比如小写字母 a 和大写字母 A 中间差了32,为什么不是26呢?为什么要在中间插入几个别的字符,搞成连续的不好吗?之前没想过这个问题,但是前两天看了一个高手的代码后,我大概明白了,这个32的差距应该是一种“炫技”的表现,它可以使得许多代码逻辑变得简单。

判断字符范围的函数

C 语言

C语言中判断的字符范围的函数都在头文件 <ctype.h> 中,常见的有下面这些

  • int isalnum(int c):检查所传的字符是否是字母和数字
  • int isalpha(int c):检查所传的字符是否是字母
  • int isdigit(int c):检查所传的字符是否是十进制数字
  • int islower(int c):检查所传的字符是否是小写字母
  • int isupper(int c):检查所传的字符是否是大写字母
  • int ispunct(int c):检查所传的字符是否是标点符号字符

C++

C++ 中其实大部分还是引用C语言里的这些函数,但是头文件的名字为 <cctype>,在C++11中加了一个 int isblank(int c) 函数。

字符判断技巧

判断两个字符互为大小写

看到这个问题第一直觉是什么?很简单的问题有木有?因为知道一个字母的大小写差了32,所以会写出下面的代码:


int isOk(char x, char y) {
    return x - y == 32 || y - x == 32;
}

不过我前两天看到一段代码,它是这样写的:

    (x ^ 32) == y;

看到这里你还以为 Aa 之间差32而不是26感到迷惑吗?简单的字符编排透露着巨大的智慧。

哨兵的使用

比如取出一个字符串 string s 中所有的数字,问题很简单,但是结尾字符的处理往往体现了编程的功底,加上一个哨兵字符可以使得编程逻辑简单许多,无须再对结尾字符特殊判断。

void find(string s) {
    s = s + 'A';
    string ans;
    for (auto c : s) {
        if (isdigit(c)) ans += c;
        else {
            cout << ans << endl;
            ans = "";
        }
    }
}

总结

  • '0' 的ASCII码是48,'A' 的ASCII码是65,'a' 的ASCII码是97
  • isdigit 可以判断字符是否是数字,isalpha 可以判断字符是否为字母
  • 一个字母的大小写对应的ASCII码正好差32,判断互为大小写时可以使用异或符号 (x ^ 32) == y
  • 字符串结尾加哨兵字符可以使得处理逻辑更加简单统一,这种编程技巧在其他结构中也常常出现

==>> 反爬链接,请勿点击,原地爆炸,概不负责!<<==

今天看到一个一直作为榜样的知识输出者宣布财富自由,满心羡慕,是真的羡慕!关键人家比我年轻,比我工作时间还短,已经依靠短短4、5年的努力达到了自由状态,不过了解他的经历会发现他确实付出了很多,而我们大多数作为普通人太安于现状了,有时候选择比努力重要,如果选择对了又付出了加倍的努力,那……

相关文章:

  • 写给自己的KMP——C++版本
  • C++中一些可以在偷懒时直接使用的函数
  • protobuf中SerializeToString和SerializePartialToString的区别
  • linux文件权限简单备忘知识点
  • 使用AddressSanitizer搭配addr2line查找C/C++内存泄漏问题
  • C++对我来说简直就是星辰大海,为了避免翻船,我选择从小河沟出发
  • cpplint中filter参数的每个可选项的含义
  • 手把手搭建一个redis集群
  • 换个角度来看看C++中的左值、右值、左值引用、右值引用
  • C/C++中的数据类型转换()/static_cast/dynamic_cast/const_cast/reinterpret_cast
  • C++11中std::move和std::forward到底干了啥
  • 使用box2dweb做一个下落的小球,宝宝玩的不亦乐乎
  • C++中使用std::sort自定义排序规则时要注意的崩溃问题
  • 从一个小题中的应用来体会下std::tie的便利之处
  • Floyd-Warshall——仅用4行代码就能解决多源最短路径问题的算法
  • Golang-长连接-状态推送
  • Gradle 5.0 正式版发布
  • Java IO学习笔记一
  • Java 实战开发之spring、logback配置及chrome开发神器(六)
  • JavaScript设计模式之工厂模式
  • laravel 用artisan创建自己的模板
  • LeetCode29.两数相除 JavaScript
  • nginx(二):进阶配置介绍--rewrite用法,压缩,https虚拟主机等
  • niucms就是以城市为分割单位,在上面 小区/乡村/同城论坛+58+团购
  • PHP变量
  • Python爬虫--- 1.3 BS4库的解析器
  • react-core-image-upload 一款轻量级图片上传裁剪插件
  • SpiderData 2019年2月16日 DApp数据排行榜
  • vue从入门到进阶:计算属性computed与侦听器watch(三)
  • XForms - 更强大的Form
  • 从tcpdump抓包看TCP/IP协议
  • 排序算法之--选择排序
  • 微服务核心架构梳理
  • 系统认识JavaScript正则表达式
  • 用Canvas画一棵二叉树
  • 自定义函数
  • nb
  • 没有任何编程基础可以直接学习python语言吗?学会后能够做什么? ...
  • #NOIP 2014# day.1 T3 飞扬的小鸟 bird
  • $con= MySQL有关填空题_2015年计算机二级考试《MySQL》提高练习题(10)
  • (51单片机)第五章-A/D和D/A工作原理-A/D
  • (C++20) consteval立即函数
  • (MIT博士)林达华老师-概率模型与计算机视觉”
  • (Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九
  • (二)构建dubbo分布式平台-平台功能导图
  • (附源码)springboot掌上博客系统 毕业设计063131
  • (欧拉)openEuler系统添加网卡文件配置流程、(欧拉)openEuler系统手动配置ipv6地址流程、(欧拉)openEuler系统网络管理说明
  • (十一)手动添加用户和文件的特殊权限
  • (一)kafka实战——kafka源码编译启动
  • (译)2019年前端性能优化清单 — 下篇
  • (转)eclipse内存溢出设置 -Xms212m -Xmx804m -XX:PermSize=250M -XX:MaxPermSize=356m
  • *p++,*(p++),*++p,(*p)++区别?
  • ..回顾17,展望18
  • .dat文件写入byte类型数组_用Python从Abaqus导出txt、dat数据
  • .desktop 桌面快捷_Linux桌面环境那么多,这几款优秀的任你选