为什么批处理文件中的特殊字符会打印为问号?

4

我之前在开发一个批处理游戏时,出现了一个问题:在命令提示符中按下Ctrl+A应该会输出笑脸符号,但它却输出问号符号。

我的程序截图

我还遇到了其他一些符号显示错误的问题:

ctrl+a Smiley face
ctrl+b Dark smiley face
ctrl+d Diamond
ctrl+e Clover
ctrl+f Ace
ctrl+n Music symbol
crtl+o Some random circlish symbol
ctrl+p Left arrow
ctrl+q Right arrow
ctrl+r Up and Down arrows
ctrl+t Line wrap symbol
ctrl+u Double s
ctrl+v Thick underscore
ctrl+w Up and down arrow with a line at the bottom
ctrl+x Up arrow
ctrl+y Down arrow

来源于Instructables文章:如何在cmd中使用特殊字符

我尝试了一下,这是cmd的截图

我目前正在运行最新更新的Windows 10专业版。我已经尝试寻找解决此问题的方法,但没有成功。感谢任何帮助。

2个回答

5

OEM Alt码在处理1-31和127这个范围内的字符时存在误导。系统的OEM代码页是ASCII字符集的超集。但是,Alt码并不代表ASCII控制字符,而是旧版IBM PC系统中有时会显示和打印ASCII控制字符的字符。例如,按下Alt+1会输入"☺"(U+263A,白色微笑脸),而不是ASCII SOH(U+0001,标题开始)。更糟糕的是,当使用WideCharToMultiByte将这些字符编码为OEM代码页时,默认的行为是使用相应的ASCII控制字符作为最佳匹配编码。因此,文本编辑器可能不会警告您所看到的内容与实际得到的不同。

控制台不会像旧版IBM PC图形字符一样显示控制字符。它会解释其中的一些字符,如U+0009(水平制表符——将光标向前移动8个空格)和U+000D(回车——将光标移动到下一行的开头),但大多数情况下它们会以当前字体的未映射字符的字形显示,例如一个带问号的方框或一个空盒子。如果要在控制台上打印"☺",则应使用控制台的宽字符API,该API适用于Windows本机Unicode(UTF-16LE)字符串。

幸运的是,CMD是一个Unicode应用程序,因此在控制台上打印"☺"不会有问题。问题在于要使用哪种编码来保存批处理脚本。唯一的通用解决方案是将批处理文件保存为UTF-8无BOM格式。您需要一个能够保存UTF-8无BOM格式的IDE或文本编辑器,例如Notepad++。

CMD使用遗留控制台代码页逐行解码批处理脚本,您可以使用chcp.com 65001命令将其更改为UTF-8。我建议不要永久更改为UTF-8,因为根据Windows版本,控制台在使用代码页65001时存在各种错误。您可以暂时切换到UTF-8以加载非ASCII字符串作为环境变量。否则,请将批处理文件的其余部分严格保持为7位ASCII,以避免本地化问题。

下面是一个示例。可能有比创建所有这些本地环境变量更通用的方法,但这只是为了证明它原则上可行。

graphics_ctl.bat

@echo off
REM ASCII Control-Character Graphics
REM File encoding: UTF-8 (no BOM)

REM Set the console to codepage 65001 (UTF-8).
for /f "tokens=2 delims=:" %%a in ('chcp.com') do set "CONSOLE_CODEPAGE=%%a"
set "CONSOLE_CODEPAGE=%CONSOLE_CODEPAGE: =%"
chcp.com 65001 >NUL

set "GCTL_WHITE_SMILING_FACE=☺"
set "GCTL_BLACK_SMILING_FACE=☻"
set "GCTL_BLACK_HEART_SUIT=♥"
set "GCTL_BLACK_DIAMOND_SUIT=♦"
set "GCTL_BLACK_CLUB_SUIT=♣"
set "GCTL_BLACK_SPADE_SUIT=♠"
set "GCTL_BULLET=•"
set "GCTL_INVERSE_BULLET=◘"
set "GCTL_WHITE_CIRCLE=○"
set "GCTL_INVERSE_WHITE_CIRCLE=◙"
set "GCTL_MALE_SIGN=♂"
set "GCTL_FEMALE_SIGN=♀"
set "GCTL_EIGHTH_NOTE=♪"
set "GCTL_BEAMED_EIGHTH_NOTES=♫"
set "GCTL_WHITE_SUN_WITH_RAYS=☼"
set "GCTL_BLACK_RIGHT_POINTER=►"
set "GCTL_BLACK_LEFT_POINTER=◄"
set "GCTL_UP_DOWN_ARROW=↕"
set "GCTL_DOUBLE_EXCLAMATION_MARK=‼"
set "GCTL_PILCROW_SIGN=¶"
set "GCTL_SECTION_SIGN=§"
set "GCTL_BLACK_RECTANGLE=▬"
set "GCTL_UP_DOWN_ARROW_WITH_BASE=↨"
set "GCTL_UP_ARROW=↑"
set "GCTL_DOWN_ARROW=↓"
set "GCTL_RIGHT_ARROW=→"
set "GCTL_LEFT_ARROW=←"
set "GCTL_RIGHT_ANGLE=∟"
set "GCTL_LEFT_RIGHT_ARROW=↔"
set "GCTL_BLACK_UP_TRIANGLE=▲"
set "GCTL_BLACK_DOWN_TRIANGLE=▼"
set "GCTL_HOUSE=⌂"

REM Restore the previous console codepage.
chcp.com %CONSOLE_CODEPAGE% >NUL

graphics_box.bat

@echo off
REM Box-Drawing Graphics
REM File encoding: UTF-8 (no BOM)

REM Set the console to codepage 65001 (UTF-8).
for /f "tokens=2 delims=:" %%a in ('chcp.com') do set "CONSOLE_CODEPAGE=%%a"
set "CONSOLE_CODEPAGE=%CONSOLE_CODEPAGE: =%"
chcp.com 65001 >NUL

set "GBOX_LIGHT_SHADE=░"
set "GBOX_MEDIUM_SHADE=▒"
set "GBOX_DARK_SHADE=▓"
set "GBOX_LIGHT_VERTICAL=│"
set "GBOX_LIGHT_VERTICAL_AND_LEFT=┤"
set "GBOX_VERTICAL_SINGLE_AND_LEFT_DOUBLE=╡"
set "GBOX_VERTICAL_DOUBLE_AND_LEFT_SINGLE=╢"
set "GBOX_DOWN_DOUBLE_AND_LEFT_SINGLE=╖"
set "GBOX_DOWN_SINGLE_AND_LEFT_DOUBLE=╕"
set "GBOX_DOUBLE_VERTICAL_AND_LEFT=╣"
set "GBOX_DOUBLE_VERTICAL=║"
set "GBOX_DOUBLE_DOWN_AND_LEFT=╗"
set "GBOX_DOUBLE_UP_AND_LEFT=╝"
set "GBOX_UP_DOUBLE_AND_LEFT_SINGLE=╜"
set "GBOX_UP_SINGLE_AND_LEFT_DOUBLE=╛"
set "GBOX_LIGHT_DOWN_AND_LEFT=┐"
set "GBOX_LIGHT_UP_AND_RIGHT=└"
set "GBOX_LIGHT_UP_AND_HORIZONTAL=┴"
set "GBOX_LIGHT_DOWN_AND_HORIZONTAL=┬"
set "GBOX_LIGHT_VERTICAL_AND_RIGHT=├"
set "GBOX_LIGHT_HORIZONTAL=─"
set "GBOX_LIGHT_VERTICAL_AND_HORIZONTAL=┼"
set "GBOX_VERTICAL_SINGLE_AND_RIGHT_DOUBLE=╞"
set "GBOX_VERTICAL_DOUBLE_AND_RIGHT_SINGLE=╟"
set "GBOX_DOUBLE_UP_AND_RIGHT=╚"
set "GBOX_DOUBLE_DOWN_AND_RIGHT=╔"
set "GBOX_DOUBLE_UP_AND_HORIZONTAL=╩"
set "GBOX_DOUBLE_DOWN_AND_HORIZONTAL=╦"
set "GBOX_DOUBLE_VERTICAL_AND_RIGHT=╠"
set "GBOX_DOUBLE_HORIZONTAL=═"
set "GBOX_DOUBLE_VERTICAL_AND_HORIZONTAL=╬"
set "GBOX_UP_SINGLE_AND_HORIZONTAL_DOUBLE=╧"
set "GBOX_UP_DOUBLE_AND_HORIZONTAL_SINGLE=╨"
set "GBOX_DOWN_SINGLE_AND_HORIZONTAL_DOUBLE=╤"
set "GBOX_DOWN_DOUBLE_AND_HORIZONTAL_SINGLE=╥"
set "GBOX_UP_DOUBLE_AND_RIGHT_SINGLE=╙"
set "GBOX_UP_SINGLE_AND_RIGHT_DOUBLE=╘"
set "GBOX_DOWN_SINGLE_AND_RIGHT_DOUBLE=╒"
set "GBOX_DOWN_DOUBLE_AND_RIGHT_SINGLE=╓"
set "GBOX_VERTICAL_DOUBLE_AND_HORIZONTAL_SINGLE=╫"
set "GBOX_VERTICAL_SINGLE_AND_HORIZONTAL_DOUBLE=╪"
set "GBOX_LIGHT_UP_AND_LEFT=┘"
set "GBOX_LIGHT_DOWN_AND_RIGHT=┌"
set "GBOX_FULL_BLOCK=█"
set "GBOX_LOWER_HALF_BLOCK=▄"
set "GBOX_LEFT_HALF_BLOCK=▌"
set "GBOX_RIGHT_HALF_BLOCK=▐"
set "GBOX_UPPER_HALF_BLOCK=▀"

REM Restore the previous console codepage.
chcp.com %CONSOLE_CODEPAGE% >NUL

graphics_test.bat

@echo off
setlocal

set "scriptdir=%~dp0"
call "%scriptdir%\graphics_ctl.bat"
call "%scriptdir%\graphics_box.bat"

echo.
echo ASCII Control-Character Graphics
echo ----------------------------------------------
echo GCTL_WHITE_SMILING_FACE      = %GCTL_WHITE_SMILING_FACE%
echo GCTL_BLACK_SMILING_FACE      = %GCTL_BLACK_SMILING_FACE%
echo GCTL_BLACK_HEART_SUIT        = %GCTL_BLACK_HEART_SUIT%
echo GCTL_BLACK_DIAMOND_SUIT      = %GCTL_BLACK_DIAMOND_SUIT%
echo GCTL_BLACK_CLUB_SUIT         = %GCTL_BLACK_CLUB_SUIT%
echo GCTL_BLACK_SPADE_SUIT        = %GCTL_BLACK_SPADE_SUIT%
echo GCTL_BULLET                  = %GCTL_BULLET%
echo GCTL_INVERSE_BULLET          = %GCTL_INVERSE_BULLET%
echo GCTL_WHITE_CIRCLE            = %GCTL_WHITE_CIRCLE%
echo GCTL_INVERSE_WHITE_CIRCLE    = %GCTL_INVERSE_WHITE_CIRCLE%
echo GCTL_MALE_SIGN               = %GCTL_MALE_SIGN%
echo GCTL_FEMALE_SIGN             = %GCTL_FEMALE_SIGN%
echo GCTL_EIGHTH_NOTE             = %GCTL_EIGHTH_NOTE%
echo GCTL_BEAMED_EIGHTH_NOTES     = %GCTL_BEAMED_EIGHTH_NOTES%
echo GCTL_WHITE_SUN_WITH_RAYS     = %GCTL_WHITE_SUN_WITH_RAYS%
echo GCTL_BLACK_RIGHT_POINTER     = %GCTL_BLACK_RIGHT_POINTER%
echo GCTL_BLACK_LEFT_POINTER      = %GCTL_BLACK_LEFT_POINTER%
echo GCTL_UP_DOWN_ARROW           = %GCTL_UP_DOWN_ARROW%
echo GCTL_DOUBLE_EXCLAMATION_MARK = %GCTL_DOUBLE_EXCLAMATION_MARK%
echo GCTL_PILCROW_SIGN            = %GCTL_PILCROW_SIGN%
echo GCTL_SECTION_SIGN            = %GCTL_SECTION_SIGN%
echo GCTL_BLACK_RECTANGLE         = %GCTL_BLACK_RECTANGLE%
echo GCTL_UP_DOWN_ARROW_WITH_BASE = %GCTL_UP_DOWN_ARROW_WITH_BASE%
echo GCTL_UP_ARROW                = %GCTL_UP_ARROW%
echo GCTL_DOWN_ARROW              = %GCTL_DOWN_ARROW%
echo GCTL_RIGHT_ARROW             = %GCTL_RIGHT_ARROW%
echo GCTL_LEFT_ARROW              = %GCTL_LEFT_ARROW%
echo GCTL_RIGHT_ANGLE             = %GCTL_RIGHT_ANGLE%
echo GCTL_LEFT_RIGHT_ARROW        = %GCTL_LEFT_RIGHT_ARROW%
echo GCTL_BLACK_UP_TRIANGLE       = %GCTL_BLACK_UP_TRIANGLE%
echo GCTL_BLACK_DOWN_TRIANGLE     = %GCTL_BLACK_DOWN_TRIANGLE%
echo GCTL_HOUSE                   = %GCTL_HOUSE%

echo.
echo Box-Drawing Graphics
echo ----------------------------------------------
echo GBOX_LIGHT_SHADE                           = %GBOX_LIGHT_SHADE%
echo GBOX_MEDIUM_SHADE                          = %GBOX_MEDIUM_SHADE%
echo GBOX_DARK_SHADE                            = %GBOX_DARK_SHADE%
echo GBOX_LIGHT_VERTICAL                        = %GBOX_LIGHT_VERTICAL%
echo GBOX_LIGHT_VERTICAL_AND_LEFT               = %GBOX_LIGHT_VERTICAL_AND_LEFT%
echo GBOX_VERTICAL_SINGLE_AND_LEFT_DOUBLE       = %GBOX_VERTICAL_SINGLE_AND_LEFT_DOUBLE%
echo GBOX_VERTICAL_DOUBLE_AND_LEFT_SINGLE       = %GBOX_VERTICAL_DOUBLE_AND_LEFT_SINGLE%
echo GBOX_DOWN_DOUBLE_AND_LEFT_SINGLE           = %GBOX_DOWN_DOUBLE_AND_LEFT_SINGLE%
echo GBOX_DOWN_SINGLE_AND_LEFT_DOUBLE           = %GBOX_DOWN_SINGLE_AND_LEFT_DOUBLE%
echo GBOX_DOUBLE_VERTICAL_AND_LEFT              = %GBOX_DOUBLE_VERTICAL_AND_LEFT%
echo GBOX_DOUBLE_VERTICAL                       = %GBOX_DOUBLE_VERTICAL%
echo GBOX_DOUBLE_DOWN_AND_LEFT                  = %GBOX_DOUBLE_DOWN_AND_LEFT%
echo GBOX_DOUBLE_UP_AND_LEFT                    = %GBOX_DOUBLE_UP_AND_LEFT%
echo GBOX_UP_DOUBLE_AND_LEFT_SINGLE             = %GBOX_UP_DOUBLE_AND_LEFT_SINGLE%
echo GBOX_UP_SINGLE_AND_LEFT_DOUBLE             = %GBOX_UP_SINGLE_AND_LEFT_DOUBLE%
echo GBOX_LIGHT_DOWN_AND_LEFT                   = %GBOX_LIGHT_DOWN_AND_LEFT%
echo GBOX_LIGHT_UP_AND_RIGHT                    = %GBOX_LIGHT_UP_AND_RIGHT%
echo GBOX_LIGHT_UP_AND_HORIZONTAL               = %GBOX_LIGHT_UP_AND_HORIZONTAL%
echo GBOX_LIGHT_DOWN_AND_HORIZONTAL             = %GBOX_LIGHT_DOWN_AND_HORIZONTAL%
echo GBOX_LIGHT_VERTICAL_AND_RIGHT              = %GBOX_LIGHT_VERTICAL_AND_RIGHT%
echo GBOX_LIGHT_HORIZONTAL                      = %GBOX_LIGHT_HORIZONTAL%
echo GBOX_LIGHT_VERTICAL_AND_HORIZONTAL         = %GBOX_LIGHT_VERTICAL_AND_HORIZONTAL%
echo GBOX_VERTICAL_SINGLE_AND_RIGHT_DOUBLE      = %GBOX_VERTICAL_SINGLE_AND_RIGHT_DOUBLE%
echo GBOX_VERTICAL_DOUBLE_AND_RIGHT_SINGLE      = %GBOX_VERTICAL_DOUBLE_AND_RIGHT_SINGLE%
echo GBOX_DOUBLE_UP_AND_RIGHT                   = %GBOX_DOUBLE_UP_AND_RIGHT%
echo GBOX_DOUBLE_DOWN_AND_RIGHT                 = %GBOX_DOUBLE_DOWN_AND_RIGHT%
echo GBOX_DOUBLE_UP_AND_HORIZONTAL              = %GBOX_DOUBLE_UP_AND_HORIZONTAL%
echo GBOX_DOUBLE_DOWN_AND_HORIZONTAL            = %GBOX_DOUBLE_DOWN_AND_HORIZONTAL%
echo GBOX_DOUBLE_VERTICAL_AND_RIGHT             = %GBOX_DOUBLE_VERTICAL_AND_RIGHT%
echo GBOX_DOUBLE_HORIZONTAL                     = %GBOX_DOUBLE_HORIZONTAL%
echo GBOX_DOUBLE_VERTICAL_AND_HORIZONTAL        = %GBOX_DOUBLE_VERTICAL_AND_HORIZONTAL%
echo GBOX_UP_SINGLE_AND_HORIZONTAL_DOUBLE       = %GBOX_UP_SINGLE_AND_HORIZONTAL_DOUBLE%
echo GBOX_UP_DOUBLE_AND_HORIZONTAL_SINGLE       = %GBOX_UP_DOUBLE_AND_HORIZONTAL_SINGLE%
echo GBOX_DOWN_SINGLE_AND_HORIZONTAL_DOUBLE     = %GBOX_DOWN_SINGLE_AND_HORIZONTAL_DOUBLE%
echo GBOX_DOWN_DOUBLE_AND_HORIZONTAL_SINGLE     = %GBOX_DOWN_DOUBLE_AND_HORIZONTAL_SINGLE%
echo GBOX_UP_DOUBLE_AND_RIGHT_SINGLE            = %GBOX_UP_DOUBLE_AND_RIGHT_SINGLE%
echo GBOX_UP_SINGLE_AND_RIGHT_DOUBLE            = %GBOX_UP_SINGLE_AND_RIGHT_DOUBLE%
echo GBOX_DOWN_SINGLE_AND_RIGHT_DOUBLE          = %GBOX_DOWN_SINGLE_AND_RIGHT_DOUBLE%
echo GBOX_DOWN_DOUBLE_AND_RIGHT_SINGLE          = %GBOX_DOWN_DOUBLE_AND_RIGHT_SINGLE%
echo GBOX_VERTICAL_DOUBLE_AND_HORIZONTAL_SINGLE = %GBOX_VERTICAL_DOUBLE_AND_HORIZONTAL_SINGLE%
echo GBOX_VERTICAL_SINGLE_AND_HORIZONTAL_DOUBLE = %GBOX_VERTICAL_SINGLE_AND_HORIZONTAL_DOUBLE%
echo GBOX_LIGHT_UP_AND_LEFT                     = %GBOX_LIGHT_UP_AND_LEFT%
echo GBOX_LIGHT_DOWN_AND_RIGHT                  = %GBOX_LIGHT_DOWN_AND_RIGHT%
echo GBOX_FULL_BLOCK                            = %GBOX_FULL_BLOCK%
echo GBOX_LOWER_HALF_BLOCK                      = %GBOX_LOWER_HALF_BLOCK%
echo GBOX_LEFT_HALF_BLOCK                       = %GBOX_LEFT_HALF_BLOCK%
echo GBOX_RIGHT_HALF_BLOCK                      = %GBOX_RIGHT_HALF_BLOCK%
echo GBOX_UPPER_HALF_BLOCK                      = %GBOX_UPPER_HALF_BLOCK%

1
谢谢!这真的帮了我很多!☺ - JoezCodes 101

0

这取决于你的代码页。你可以在命令提示符下输入chcp来检查它,它会显示你的代码页。搜索一下,你会找到一个可以编写的字符列表。基本上,它会告诉你可以输入哪些“特殊”字符将被显示。例如,我的是850(像很多其他人一样),所以无法显示笑脸。你可以通过以下方式更改你的代码页:

Open Windows Control Panel
Select Region and Language
Click on the Administrative tab
Under Language for non-Unicode programs, click on Change System Locale
Choose the locale
Click OK

就这些了,我想。希望我有所帮助!


有趣。我会去看一下。谢谢你的回复。 - JoezCodes 101

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