鱼C论坛

 找回密码
 立即注册
查看: 142|回复: 2

[已解决]指针与数组一节中,关于获取中英文混写字符串的长度

[复制链接]
发表于 2024-10-27 16:00:10 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
在我上传的图片中,是小甲鱼在他的系统中运行得到的规律。发现,每个中文字符在他的系统中是占用 4 个字节的存储空间,并且都是负数。那么,为什么以此规律,我们只要检测一个字符对应的整型值是否为负数,如果是(中文字符),则将指针往后移动两个字节呢?这里前面的4个字节与后文的往后移动两个字节是怎么一一对应得到的规律?
最佳答案
2024-10-27 16:58:04
本帖最后由 jackz007 于 2024-10-27 17:13 编辑

        应该指出,图片中的 str[3] = 0 并不是 "中" 字占用的第 4 个字节,楼主应该明白,C 语言的每一个字符串在末尾都有一个字符串结束标志 '\0',这个 str[3] 正是这个结束标志,也就是说,一个 3 个字符的字符串实际占用 4 个字节,每个字符串所占用的字节数量都是 n + 1。

        先明确 2 点:
        1、西文字符每个字符占用 1 个字节,其 ASCII 编码范围为 0 ~ 127,属于正值;   
        2、汉字占用的字节数取决于操作系统,在 Windows 系统中,汉字采用 GBK 编码,每个汉字占用 2 个字节,每个字节的都是负值;在 Linux 系统中,汉字采用 UTF-8 编码,每个汉字占用 3 个字节,每个字节都是负值;
        由此可见,同一个程序在不同的操作系统上运行是必须要修改代码的。
【Windows】:
#include<stdio.h>

int main(void)
{
        char str[] = "fishC * 中国 * China" , * p ;
        int length                                ;
        for(length = 0 , p = str ; * p ; length ++) {
                if(* p > 0) p ++                  ;
                else p += 2                       ; // Windows
        }
        printf("%s\n" , str)                      ;
        printf("%d\n" , length)                   ;
}
【Linux】
#include<stdio.h>

int main(void)
{
        char str[] = "fishC * 中国 * China" , * p ;
        int length                                ;
        for(length = 0 , p = str ; * p ; length ++) {
                if(* p > 0) p ++                  ;
                else p += 3                       ; // Linux
        }
        printf("%s\n" , str)                      ;
        printf("%d\n" , length)                   ;
}
        编译、运行实况:
D:\[exercise]\C>g++ -o x x.c

D:\[exercise]\C>x
fishC * 中国 * China
18

D:\[exercise]\C>
微信图片_20241027155733.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-10-27 16:00:20 | 显示全部楼层
在处理中英文混合字符串时,字符是否为负数取决于字符编码。在某些系统和编码中,中文字符会占用多个字节(比如UTF-8或UTF-16),并且有时,高位字节会出现负数。

如果检测到一个字符是负数(表示它是中文字符的一部分),通常你的逻辑是把指针移动多个字节来跳过这个字符。至于为什么移动两个字节,这具体依赖于编码方式:

1. **UTF-16**:中文字符通常占用2个字(4字节),所以可能要移动2字节跳过高位。

2. **UTF-8**:中文字符占用3个字节,但如果你的规则经过测试是2字节跳过某些场合,可能是简化的假设。

这个规律的适用条件是根据编码方式和实现细节的测试得出的。因此,在不同环境或编码下,可能会有不同的移动策略。确保在使用时确认具体编码和验证策略的有效性。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-10-27 16:58:04 | 显示全部楼层    本楼为最佳答案   
本帖最后由 jackz007 于 2024-10-27 17:13 编辑

        应该指出,图片中的 str[3] = 0 并不是 "中" 字占用的第 4 个字节,楼主应该明白,C 语言的每一个字符串在末尾都有一个字符串结束标志 '\0',这个 str[3] 正是这个结束标志,也就是说,一个 3 个字符的字符串实际占用 4 个字节,每个字符串所占用的字节数量都是 n + 1。

        先明确 2 点:
        1、西文字符每个字符占用 1 个字节,其 ASCII 编码范围为 0 ~ 127,属于正值;   
        2、汉字占用的字节数取决于操作系统,在 Windows 系统中,汉字采用 GBK 编码,每个汉字占用 2 个字节,每个字节的都是负值;在 Linux 系统中,汉字采用 UTF-8 编码,每个汉字占用 3 个字节,每个字节都是负值;
        由此可见,同一个程序在不同的操作系统上运行是必须要修改代码的。
【Windows】:
#include<stdio.h>

int main(void)
{
        char str[] = "fishC * 中国 * China" , * p ;
        int length                                ;
        for(length = 0 , p = str ; * p ; length ++) {
                if(* p > 0) p ++                  ;
                else p += 2                       ; // Windows
        }
        printf("%s\n" , str)                      ;
        printf("%d\n" , length)                   ;
}
【Linux】
#include<stdio.h>

int main(void)
{
        char str[] = "fishC * 中国 * China" , * p ;
        int length                                ;
        for(length = 0 , p = str ; * p ; length ++) {
                if(* p > 0) p ++                  ;
                else p += 3                       ; // Linux
        }
        printf("%s\n" , str)                      ;
        printf("%d\n" , length)                   ;
}
        编译、运行实况:
D:\[exercise]\C>g++ -o x x.c

D:\[exercise]\C>x
fishC * 中国 * China
18

D:\[exercise]\C>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-21 19:53

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表