打印
[其他产品]

C语言 用奇奇怪怪的代码统计字符串字符个数,还怪好用的

[复制链接]
1178|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
laocuo1142|  楼主 | 2024-4-17 09:26 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在介绍统计数组元素个数之前,有必要先单独介绍以下字符数组中的元素统计方法。
统计字符串字符个数
首先,可以确定的一点是,C语言中strlen()函数返回的是字符串的字节大小,并不是具体的字符个数,因为英文字符或标点符号等只占据一个字节,如此使用strlen()函数确实可以获取字符串的元素个数,但是如果字符串同时包含了汉字和英文,而且汉字在不同的编码中占用的字节大小是不一样的,比如GBK中,一般是占据两个字节的,在UTF-8的编码中一般占据三个字节。

除此之外,另一个可以大致确定的是,在不管是使用循环遍历还是使用索引的方式来访问字符串(字符数组)的时候,都是一个字节一个字节地遍历访问的,这就会导致一些情况。

循环和索引访问对多字节字符
使用C语言的循环和索引来遍历统计字符串的字符个数时,如果遇到大于1个字节的字符时,在同一个字符上会经历多次“访问”,比如下面的这段代码(源文件使用GBK编码,每个汉字字符占2个字节);

#include "stdio.h"
#include "string.h"

int strLen(char *str){
    int i = 0;
    do{
        if(str[i] != '\0'){
            i++;
        }else{
            break;
        }
    }while(1);
    return i;
}

int main() {
    char str[] = "全栈开发助手";
    int num = strLen(str);
    printf("%d\n",num);
    return 0;
}
代码编译,得到输出:

12
如上代码,每个字符占据两个字节,通过do while循环,str[i]访问的每个字符的时候,其实逐个访问的是字符中的字节,因此,得到的统计个数会为12,与字符串内置的strlen()得到的一样。

那要怎么统计字符串中字符的个数呢?

奇奇怪怪的代码及设计思路
个人查到的资料是,在GBK编码中,凡是占用两个字节的字符的每个字节上的编码值都大于127,如果是一个字节的字符的话,则在0到127之间。

因此,鄙人设计的程序思路是:可以在循环的代码中,使用索引访问字符串字符的每个字节的时候,判断该字节中的编码值是否大于127,如果是,则计数器count加上0.5(说明是两个字节构成一个字符),如果不是,则加1(说明是一个字节构成一个字符),值得一提的是,在比较之前,需要将索引访问的编码值通过(unsigned char)进行强制转换为无符号整型,具体代码如下:

#include "stdio.h"
#include "string.h"

float strLen(char *str){
    int i = 0;
    float count = 0;
    do{
        if(str[i] != '\0'){
            if((unsigned char)str[i] > 127){
                count = count + 0.5;
            }else{
                count++;
            }
            i++;  
        }else{
            break;
        }
    }while(1);
    return count;
}

int main() {
    char str[] = "全栈开发助手,hello";
   
    float num = strLen(str);
    printf("%d\n",(int)num);

    return 0;
}
代码编译运行,得到输出:

12
重点提示:这个函数只适用于GBK编码的源文件,如果是其它编码的源文件,可能要适当地进行更改;另外,鄙人使用的操作系统是Window10,编译器是MinGW!另外,C语言中其实还有一些方法可以用于统计字符串的字符个数(非字节为单位),只是看上去比较复杂,可能涉及到位的运算,这里暂时就不介绍了!

还有,如果还有其它更简单的更好的方法,读者朋友们也可以在留言处留言!

免责声明:内容仅供参考,不保证正确性!

使用特权

评论回复
沙发
forgot| | 2024-4-17 17:25 | 只看该作者
计算的是字符串str的长度,从字符的首地址开始遍历,以 '\0' 为结束标志,然后将计算的长度返回,计算的长度并不包含'\0'

使用特权

评论回复
板凳
稳稳の幸福| | 2024-4-23 23:20 | 只看该作者
主要是要知道字符串的结束符是什么。知道了结束符就一直查找并计数,直到查找到这个结束符。

使用特权

评论回复
地板
稳稳の幸福| | 2024-4-23 23:23 | 只看该作者
结束符是不是占用了这个字符串的空间呢?
比如“12345”存储的时候是占用5个字节还是占用6个字节?

使用特权

评论回复
5
wahahaheihei| | 2024-4-28 21:46 | 只看该作者
如果考虑存储空间,还要加一。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1213

主题

5359

帖子

12

粉丝