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

如何用std::cin将字符ú正确存入char数组?解决存储为£的问题

解决std::cin读取ú时存储为£(163)的问题

这个问题本质是编码不匹配导致的——控制台输入使用的字符编码,和你期望存储的编码里,ú对应的字节值不一样。你看到的163是字节的十进制值,在当前编码里它对应£,但你希望这个字节值对应ú,那我们得从编码对齐入手解决。

下面分平台给你具体方案:

Windows平台

方法1:直接修改控制台编码

如果你的目标是让输入的ú直接被读取为字节163(十进制),且控制台显示这个字节时也显示ú,可以修改控制台的代码页为CP850(DOS编码,其中ú的字节值就是163)。

用Windows API在程序启动时设置编码:

#include <windows.h>
#include <iostream>

int main() {
    // 设置控制台输入/输出代码页为CP850
    SetConsoleCP(850);
    SetConsoleOutputCP(850);

    char buf[100];
    std::cin >> buf;

    // 验证存储的字节值和显示效果
    for (int i = 0; buf[i] != '\0'; ++i) {
        // 转成unsigned char避免有符号char的负数问题
        unsigned char byte = static_cast<unsigned char>(buf[i]);
        std::cout << "字符: " << buf[i] << ", 十进制值: " << static_cast<int>(byte) << "\n";
    }

    return 0;
}

运行后输入ú,你会看到存储的字节是163,且控制台显示的也是ú。

方法2:编码转换(不修改控制台编码)

如果不想改动控制台默认编码(比如默认是CP1252),可以先读取输入,再把编码从当前控制台编码转换为CP850:

#include <windows.h>
#include <iostream>
#include <string>

int main() {
    char input_buf[100];
    std::cin >> input_buf;

    // 1. 把CP1252的单字节字符串转成宽字符
    int wide_len = MultiByteToWideChar(1252, 0, input_buf, -1, nullptr, 0);
    wchar_t* wide_str = new wchar_t[wide_len];
    MultiByteToWideChar(1252, 0, input_buf, -1, wide_str, wide_len);

    // 2. 把宽字符转成CP850的单字节字符串
    int cp850_len = WideCharToMultiByte(850, 0, wide_str, -1, nullptr, 0, nullptr, nullptr);
    char* cp850_buf = new char[cp850_len];
    WideCharToMultiByte(850, 0, wide_str, -1, cp850_buf, cp850_len, nullptr, nullptr);

    // 验证结果
    std::cout << "转换后字符串: " << cp850_buf << "\n";
    for (int i = 0; cp850_buf[i] != '\0'; ++i) {
        unsigned char byte = static_cast<unsigned char>(cp850_buf[i]);
        std::cout << "字符: " << cp850_buf[i] << ", 十进制值: " << static_cast<int>(byte) << "\n";
    }

    // 释放内存
    delete[] wide_str;
    delete[] cp850_buf;
    return 0;
}

这样输入的ú(CP1252里是字节250)会被转换成CP850的163,存储到char数组中。

Linux平台

Linux默认用UTF-8编码,ú是两个字节(0xC3 0xBA)。要把它转换成单字节163(对应CP850的ú),可以用iconv库做编码转换:

#include <iostream>
#include <cstring>
#include <iconv.h>

int main() {
    char input[100];
    std::cin >> input;

    // 初始化编码转换器:从UTF-8转CP850
    iconv_t conv_handle = iconv_open("CP850", "UTF-8");
    if (conv_handle == (iconv_t)-1) {
        perror("初始化编码转换器失败");
        return 1;
    }

    size_t in_len = strlen(input);
    size_t out_len = 100;
    char* in_buf = input;
    char output[100];
    char* out_buf = output;

    // 执行转换
    if (iconv(conv_handle, &in_buf, &in_len, &out_buf, &out_len) == (size_t)-1) {
        perror("编码转换失败");
        iconv_close(conv_handle);
        return 1;
    }

    // 添加字符串结束符
    *out_buf = '\0';

    // 验证结果
    std::cout << "转换后字符串: " << output << "\n";
    for (int i = 0; output[i] != '\0'; ++i) {
        unsigned char byte = static_cast<unsigned char>(output[i]);
        std::cout << "字符: " << output[i] << ", 十进制值: " << static_cast<int>(byte) << "\n";
    }

    iconv_close(conv_handle);
    return 0;
}

编译时需要链接iconv库:

g++ -o char_encoding_fix char_encoding_fix.cpp -liconv

关键注意点

  • char类型默认是有符号的,所以字节值大于127时会显示为负数,输出时一定要转成unsigned char再转int,才能得到正确的十进制值(比如163而不是-93)。
  • 你期望的163对应ú,本质是指定了CP850编码下的字节值,所以所有方案都是围绕让输入/存储的编码对齐到CP850来实现的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:35:46