You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言如何将Unicode转义码转换为对应字符并正常打印

C语言Unicode转义序列(\uXXXX)转可显示字符方案

你给出的示例代码存在笔误,定义的string数组未使用,直接用了未定义的buffer,调试时需要先修正这个问题。你当前输出的\u25BA是因为你写的\\u25BA在编译后实际存储的是普通字符\、u、2、5、B、A,不会被C编译器识别为Unicode转义,所以直接输出就是原样内容,对应两种使用场景可以用以下方案解决:

场景1:转义序列是写死在代码的字符串字面量中

如果你用的是C11及以上标准的编译器,直接去掉转义反斜杠即可,编译器会自动把\uXXXX转成对应Unicode字符的UTF-8编码:

#include <stdio.h>
#include <string.h>
#ifdef _WIN32
#include <windows.h>
#endif

int main() {
    #ifdef _WIN32
    SetConsoleOutputCP(CP_UTF8);
    #endif
    char buffer[32];
    memset(buffer, 0, sizeof(buffer));
    // 修正转义写法,去掉u前面的多余转义反斜杠
    strcpy(buffer, "{\"key\":\"\u25BA\"}");
    printf("%s\n", buffer); // 输出 {"key":"►"}
    return 0;
}

注意:Windows环境下需要提前调用SetConsoleOutputCP(CP_UTF8);设置控制台输出编码为UTF-8,否则会显示乱码

场景2:转义序列是运行时动态获取的

如果字符串是从接口、文件等渠道动态读取的自带\u转义,编译器无法提前处理,需要自己实现解析逻辑,解析步骤如下:

  • 遍历输入字符串,遇到\u序列时,读取后续4位十六进制字符转换为整数Unicode码点
  • 将Unicode码点编码为1~4字节的UTF-8序列写入输出缓冲区
  • 非\u前缀的普通字符直接写入输出缓冲区

可用的简单实现代码如下:

#include <stdio.h>
#include <string.h>
#include <stdint.h>
#ifdef _WIN32
#include <windows.h>
#endif

// 把\uXXXX转义的字符串转换为UTF-8编码的字符串
int unicode_unescape(const char *input, char *output, int output_len) {
    const char *p = input;
    char *q = output;
    int remain = output_len;
    while (*p != '\0' && remain > 0) {
        if (*p == '\\' && *(p+1) == 'u') {
            // 读取4位十六进制转码点
            uint32_t codepoint = 0;
            int i;
            for (i = 0; i < 4; i++) {
                char c = *(p + 2 + i);
                codepoint <<= 4;
                if (c >= '0' && c <= '9') codepoint += c - '0';
                else if (c >= 'a' && c <= 'f') codepoint += 10 + c - 'a';
                else if (c >= 'A' && c <= 'F') codepoint += 10 + c - 'A';
                else break;
            }
            if (i != 4) {
                // 非法\u转义直接拷贝
                *q++ = *p++;
                remain--;
                continue;
            }
            p += 6;
            // 码点转UTF-8编码
            if (codepoint <= 0x7F) {
                *q++ = codepoint;
                remain--;
            } else if (codepoint <= 0x7FF) {
                if (remain < 2) break;
                *q++ = 0xC0 | (codepoint >> 6);
                *q++ = 0x80 | (codepoint & 0x3F);
                remain -= 2;
            } else if (codepoint <= 0xFFFF) {
                if (remain < 3) break;
                *q++ = 0xE0 | (codepoint >> 12);
                *q++ = 0x80 | ((codepoint >> 6) & 0x3F);
                *q++ = 0x80 | (codepoint & 0x3F);
                remain -= 3;
            } else if (codepoint <= 0x10FFFF) {
                if (remain < 4) break;
                *q++ = 0xF0 | (codepoint >> 18);
                *q++ = 0x80 | ((codepoint >> 12) & 0x3F);
                *q++ = 0x80 | ((codepoint >> 6) & 0x3F);
                *q++ = 0x80 | (codepoint & 0x3F);
                remain -= 4;
            }
        } else {
            *q++ = *p++;
            remain--;
        }
    }
    if (remain > 0) *q = '\0';
    else output[output_len - 1] = '\0';
    return q - output;
}

int main() {
    #ifdef _WIN32
    SetConsoleOutputCP(CP_UTF8);
    #endif
    char buffer[32] = "{\"key\":\"\\u25BA\"}";
    char output[32];
    unicode_unescape(buffer, output, sizeof(output));
    printf("%s\n", output); // 输出 {"key":"►"}
    return 0;
}

如果需要兼容代理对(比如\uD83D\uDE00这类emoji的转义写法),需要额外添加代理对合并的逻辑,上面的实现仅处理单个\uXXXX对应BMP平面码点的场景

内容的提问来源于stack exchange,提问作者dark_vidor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 05:06:04