鱼C论坛

 找回密码
 立即注册
查看: 2106|回复: 7

输出中文的时候乱码

[复制链接]
发表于 2023-4-17 10:25:34 | 显示全部楼层 |阅读模式
10鱼币
以下是代码清单
#include <stdio.h>
#include <string.h>

#define MAX 1024

int main()
{
&#160; &#160; char str1[MAX];
&#160; &#160; char *pstr1 = str1;
&#160; &#160; int num, length;

&#160; &#160; printf("请输入一个字符串到 str1 中:");
&#160; &#160; fgets(str1, MAX, stdin);
&#160; &#160; printf("开始拷贝 str1 的内容至 str2 中...\n");
&#160; &#160;
&#160; &#160;
&#160; &#160; printf("请输入需要拷贝的字符个数:");
&#160; &#160; scanf("%d", &length);

&#160; &#160; char str2[length];
&#160; &#160; char *pstr2 = str2;

&#160; &#160; for(num = 0; num < length; num++, pstr1++, pstr2++)
&#160; &#160; {
&#160; &#160; &#160; &#160; *pstr2 = *pstr1;
&#160; &#160; &#160; &#160; if(*pstr1 < 0)
&#160; &#160; &#160; &#160; {
&#160; &#160; &#160; &#160; &#160; &#160; *pstr2 = *pstr1;
&#160; &#160; &#160; &#160; &#160; &#160; *pstr2 = *pstr1;
&#160; &#160; &#160; &#160; }
&#160; &#160; }
&#160; &#160; *pstr2 = '\0';

&#160; &#160; printf("拷贝完毕!现在 str2 中的内容是:%s", str2);

&#160; &#160; return 0;

}

以下是输出结果
请输入一个字符串到 str1 中:鱼c工作室
开始拷贝 str1 的内容至 str2 中...
请输入需要拷贝的字符个数:2
拷贝完毕!现在 str2 中的内容是:&#65533;c

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-4-17 10:34:02 | 显示全部楼层
这个问题是因为在处理中文字符时,没有正确处理多字节字符。中文字符在 UTF-8 编码中占用 3 个字节,而你的代码中将每个字符都当作一个字节来处理,导致中文字符被截断,输出乱码。

你可以尝试使用以下修改过的代码,这个版本的代码能够正确处理多字节的 UTF-8 字符:
#include <stdio.h>
#include <string.h>
#include <locale.h>

#define MAX 1024

int main()
{
    setlocale(LC_ALL, "en_US.UTF-8");

    char str1[MAX];
    char *pstr1 = str1;
    int num, length;

    printf("请输入一个字符串到 str1 中:");
    fgets(str1, MAX, stdin);
    printf("开始拷贝 str1 的内容至 str2 中...\n");

    printf("请输入需要拷贝的字符个数:");
    scanf("%d", &length);

    char str2[MAX];
    char *pstr2 = str2;

    for(num = 0; num < length;)
    {
        *pstr2 = *pstr1;

        if((*pstr1 & 0xC0) == 0xC0) // 判断是否为多字节字符的开始
        {
            pstr1++;
            pstr2++;
            *pstr2 = *pstr1;
            num++;
        }
        else if((*pstr1 & 0x80) == 0) // 判断是否为单字节字符
        {
            num++;
        }

        pstr1++;
        pstr2++;
    }
    *pstr2 = '\0';

    printf("拷贝完毕!现在 str2 中的内容是:%s", str2);

    return 0;
}

这个版本的代码在处理字符时会检查字符的字节,如果是多字节字符,它会将整个字符(包括所有字节)一起复制。这样就不会出现乱码问题了。注意,在代码开始时,需要调用 setlocale(LC_ALL, "en_US.UTF-8"); 设置地区和字符编码,以便程序正确处理多字节字符。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-4-17 10:44:41 | 显示全部楼层
isdkz 发表于 2023-4-17 10:34
这个问题是因为在处理中文字符时,没有正确处理多字节字符。中文字符在 UTF-8 编码中占用 3 个字节,而你的 ...

这个输出还是不能正常进行
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-4-21 20:58:01 | 显示全部楼层
本帖最后由 jackz007 于 2023-4-21 21:05 编辑

       问题可能出在 Windows 10+ 系统下,Windows 记事本缺省采用 "UTF-8" 编码,而 CMD 窗口采用的却是 "GBK" 编码,由于二者的汉字编码产生了错位,从而导致汉字乱码。
       用 Windows 记事本打开源代码文件,然后点击 "文件 > 另存为",在 "保存" 按钮左边有一个 "编码" 选项,点击其旁边的下拉菜单,选择 "ANSI",然后点击 "保存",这个时候再重新编译、运行试试。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-5-1 20:43:20 | 显示全部楼层
这个输出结果的问题在于,被复制到str2中的中文字符是以两个连续的“?”表示的(即"&#65533;"),而不是实际的中文字符。这是因为 printf 无法正确输出UTF-8编码的中文字符串("\xe9\xb1\xbc\xe5\xc|\x67\xe4\xbd\x9c\xe5\xae\xa4"),而将其识别为ASCII字符集中不存在的一些字符,显示成了“?”。

要解决这个问题,可以使用宽字符类型和对应的printf函数wprintf()来输出宽字符的内容。以下是对代码的修改:
#include <stdio.h>
#include <string.h>

#define MAX 1024

int main()
{
    wchar_t str1[MAX];
    wchar_t *pstr1 = str1;
    int num, length;

    wprintf(L"请输入一个字符串到 str1 中:");
    fgetws(str1, MAX, stdin);
    wprintf(L"开始拷贝 str1 的内容至 str2 中...\n\n");

    wprintf(L"请输入需要拷贝的字符个数:");
    scanf("%d", &length);

    wchar_t str2[length];
    wchar_t *pstr2 = str2;

    for (num = 0; num < length; num++, pstr1++, pstr2++) {
        *pstr2 = *pstr1;
        if (*pstr1 < 0) {
            *pstr2 = *pstr1;
            *pstr2 = *pstr1;
        }
    }
    *pstr2 = L'\0';

    wprintf(L"拷贝完毕!现在 str2 中的内容是:%ls", str2);

    return 0;

}
需要注意的是,对于宽字符类型,以L开头的字母作为前缀表示。同时,输入字符也需要使用fgetws()函数获取。输出时,可以使用wprintf()和占位符%ls来打印宽字符类型的字符串。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-5-2 14:58:07 | 显示全部楼层
CHCP 65001
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-5-3 10:05:09 | 显示全部楼层
666
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-6-9 08:57:21 From FishC Mobile | 显示全部楼层
vscode 将文件转为 utf8 编码。使用 windows terminal 或其他使用 utf8 编码渲染的终端运行。

二者要匹配。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-23 18:43

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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