输出中文的时候乱码
以下是代码清单#include <stdio.h>
#include <string.h>
#define MAX 1024
int main()
{
char str1;
char *pstr1 = str1;
int num, length;
printf("请输入一个字符串到 str1 中:");
fgets(str1, MAX, stdin);
printf("开始拷贝 str1 的内容至 str2 中...\n");
printf("请输入需要拷贝的字符个数:");
scanf("%d", &length);
char str2;
char *pstr2 = str2;
for(num = 0; num < length; num++, pstr1++, pstr2++)
{
*pstr2 = *pstr1;
if(*pstr1 < 0)
{
*pstr2 = *pstr1;
*pstr2 = *pstr1;
}
}
*pstr2 = '\0';
printf("拷贝完毕!现在 str2 中的内容是:%s", str2);
return 0;
}
以下是输出结果
请输入一个字符串到 str1 中:鱼c工作室
开始拷贝 str1 的内容至 str2 中...
请输入需要拷贝的字符个数:2
拷贝完毕!现在 str2 中的内容是:�c 这个问题是因为在处理中文字符时,没有正确处理多字节字符。中文字符在 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;
char *pstr1 = str1;
int num, length;
printf("请输入一个字符串到 str1 中:");
fgets(str1, MAX, stdin);
printf("开始拷贝 str1 的内容至 str2 中...\n");
printf("请输入需要拷贝的字符个数:");
scanf("%d", &length);
char str2;
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"); 设置地区和字符编码,以便程序正确处理多字节字符。 isdkz 发表于 2023-4-17 10:34
这个问题是因为在处理中文字符时,没有正确处理多字节字符。中文字符在 UTF-8 编码中占用 3 个字节,而你的 ...
这个输出还是不能正常进行 本帖最后由 jackz007 于 2023-4-21 21:05 编辑
问题可能出在 Windows 10+ 系统下,Windows 记事本缺省采用 "UTF-8" 编码,而 CMD 窗口采用的却是 "GBK" 编码,由于二者的汉字编码产生了错位,从而导致汉字乱码。
用 Windows 记事本打开源代码文件,然后点击 "文件 > 另存为",在 "保存" 按钮左边有一个 "编码" 选项,点击其旁边的下拉菜单,选择 "ANSI",然后点击 "保存",这个时候再重新编译、运行试试。 这个输出结果的问题在于,被复制到str2中的中文字符是以两个连续的“?”表示的(即"�"),而不是实际的中文字符。这是因为 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;
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;
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来打印宽字符类型的字符串。 CHCP 65001 666 vscode 将文件转为 utf8 编码。使用 windows terminal 或其他使用 utf8 编码渲染的终端运行。
二者要匹配。
页:
[1]