C++在Windows控制台打印特殊ASCII字符

3

在搜索和尝试各种方法两个小时后,我正在为尝试将特殊ASCII字符打印到控制台而苦恼!(C ++)

typedef unsigned char UCHAR;

int main()
{
  UCHAR c = '¥';
  cout << c;

  return 0;
}

为什么这段代码打印的是Ñ (209),而不是¥ (165)?

我尝试过:

SetConsoleCP(CP_UTF8);
SetConsoleOutputCP(CP_UTF8);

但是无论我传递哪些值,似乎都没有任何作用。

有人建议通过注册表更改控制台的字体。但那太荒谬了。我不希望我的最终用户必须开始更改注册表值才能运行我的程序...

真正奇怪的是,如果我将所有ASCII字符打印到文件中(使用ofstream),它们在记事本和Visual Studio编辑器(2012专业版)中都显示正确。

ofstream file("ASCII.txt");;
if (file.is_open())
{
    UCHAR c = 0;
    for (int i = 0; i < 256; i++)
    {
        c++;
        file << c << "\t|\t" << (int)c << endl;
    }
}
file.close();

任何帮助都非常感激。谢谢!

1
жҲ‘ж•ўжү“иөҢпјҢtypeе‘Ҫд»Өе’ҢдҪ зҡ„зЁӢеәҸеҒҡзҡ„жҳҜдёҖж ·зҡ„дәӢжғ…гҖӮжү“ејҖдёҖдёӘе‘Ҫд»ӨиЎҢзӘ—еҸЈпјҢиҫ“е…Ҙtype ASCII.txtпјҢзңӢзңӢжҺ§еҲ¶еҸ°иҫ“еҮәдәҶд»Җд№ҲгҖӮ - undefined
在互联网上搜索“Microsoft代码页”。 - undefined
@PaulMcKenzie 我对"type"命令并不熟悉,而且我只是简单地在谷歌上搜索了一下,结果只有关于预期的 "typeof" 和 "typedef" 函数的结果。我觉得你可能误读了我的问题。底部的代码部分只是用来测试实际ASCII值的。我并不打算在最终程序中使用它。 - undefined
1
@BenSeawalker 他指的是DOS的type命令。 - undefined
@kfsone 没有必要这样做。无论如何,我已经尝试了在这里找到的每个代码:https://msdn.microsoft.com/en-us/library/windows/desktop/dd317756(v=vs.85).aspx 使用SetConsoleCP()和SetConsoleOutputCP(),但是没有任何一个对输出产生影响。我还打开了cmd并使用"dhcp 1252",然后从该窗口而不是VS调试器中运行我的程序,但仍然没有变化。 - undefined
显示剩余14条评论
2个回答

4
欢迎来到编码之苦 :(
#include <iostream>
#include <windows>

int main() {
    SetConsoleCP(437);
    SetConsoleOutputCP(437);
    std::cout << (char)157 << "\n";
}

生成:

编译和执行结果

问题在于您的源文件不是CP437格式,因此该字符的值与您尝试打印的值不同(正如您所注意到的,在您的源文件中,它的值为165,而在CP437中是另一个字符)。

https://en.wikipedia.org/wiki/Code_page_437


SetConsoleCP(437); SetConsoleOutputCP(437);cout << '¥'; 仍然打印出 'Ñ' :( - undefined
哦,好吧,谢谢你的帮助。你能把你获取ASCII码的网站链接发给我吗?我看到的所有网站都说char是“190”,而不是“157”。 - undefined
这是答案的最后一行。如果我使用CP 437编码保存文件,cout << '¥'; 对我有效。 - undefined
我用437编码保存了所有的.cpp和.h文件,并清理/重新构建了项目,但仍然没有效果。:( - undefined
没关系。我重新启动了VS,现在一切都运行得非常顺利!谢谢@kfsone,我从来没有想过要改变源文件的编码方式。哈哈 - undefined

-1
我在MSVS Windows 11上有一个可运行的代码。 关键是你需要告诉编译器:
你想描述/输入一个以u8"\uxxx ..."或u8""(复制/粘贴)或u8"\U0001F600"编码为UTF-8的字符。 为此,你需要在开发者命令行中输入: chcp 65001 Enter 你会看到:Active code page: 65001。 或者你可以保留当前的代码页, 你在cmd中输入chcp,可能会看到: Active code page: 1250 但你需要使用以下命令进行编译: cl /W4 /EHsc /source-charset:utf-8 mbs_extended.cpp mbs_extended.cpp 这样,你的代码u8"\uxxx ..."或u8""(复制/粘贴)或u8"\U0001F600"将被翻译为一系列以UTF-8中的数字/代码存储在提供的char中。 当打印该char时,因为你使用了chcp 65001 Enter,输出将被翻译为所需的Unicode字符。 你可以尝试上面的代码,仔细阅读注释。
输入以下代码://cl /W4 /EHsc /source-charset:utf-8 /execution-charset:utf-8,如果在chcp Enter之后,Active code page是:1250 -> 这将将chcp的活动代码更改为:65001 // 当你在开发者命令行中输入chcp Enter时,输出可能是:Active code page: 1250,或其他。 // 如果你输入chcp 65001 Enter,你将得到Active code page: 65001 // 所以如果在cmd中首先输入:chcp 65001,你可以使用以下命令进行编译: //cl /W4 /EHsc /source-charset:utf-8 mbs_extended.cpp mbs_extended.cpp //执行(输出)字符集是在您在cmd中键入chcp 65001时决定的,或者如果活动代码页为1250时,您使用cl进行编译时决定的.../execution-charset:utf-8...
#include <iostream>

#include <windows.h>

using namespace std;

int main ()
{
    
    // SetConsoleOutputCP(CP_UTF8);
    // If you compile with: cl /W4 /EHsc /source-charset:utf-8 mbs_extended.cpp mbs_extended.cpp and Active code page: 1250, -> Uncomment line before, and surprise:
    // At the end of Program,
    // Active code page: 1250
    const char *text = u8"This text is in UTF-8. ¡Olé! 佻\n";
    std::cout << text;
    
    char *s = u8"\u2193";  //universal code name for: ↓
                           // might be possible to use char8_t specially designed for UTF-8 if compile with /std:c++20 or latest
    printf("\nSymbol: %s\n", s);
    printf("  length: %zu\n", strlen(s));
    size_t sz0 = strlen(s);
    cout << "Arrow hexcode: ";
    for(int i = 0; i < sz0; i++)
    {
        printf("%X ", (unsigned char) s[i] );
    }
    cout << endl;
    
    char *s1 = u8"";
    printf("\nSymbol: %s\n", s1);
    size_t sz = strlen(s1);
    printf("  length: %zu\n", strlen(s1));
    
    cout << "Smiley hexcode: ";
    for(int i = 0; i < sz; i++)
    {
        printf("%X ", (unsigned char) s1[i] );
    }
    cout << endl;
    
    
    char *s2 = u8"\U0001F600";  //universal code name for:  See the difference between: u8"\U0001F600" and u8"\u2193" (UTF-32 vs UTF-16), (8 vs 4)
                                // /source-charset:utf-8 and the Prefix u8
    printf("\nSymbol: %s\n", s2);
    size_t sz1 = strlen(s2);
    printf("  length: %zu\n", strlen(s2));
    
    cout << "Smiley hexcode: ";
    for(int i = 0; i < sz1; i++)
    {
        printf("%X ", (unsigned char) s2[i] );
    }
    cout << endl;
    
    return 0;
}
// If you uncomment SetConsoleOutputCP(CP_UTF8); , Remember, Active code page was: 1250 and you did'nt modify with chcp in cmd line.
// So either chcp 65001 in cmd line either SetConsoleOutputCP(CP_UTF8), either cl.../execution-charset:utf-8
// After program finish execution,
// Active code page: 65001 (UTF-8), 
//(multi byte string), (one or more 2 or 3 bytes, for characters)
// This is the work of SetConsoleOutputCP(CP_UTF8);`   

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接