问题
So I want to print Jäger bomb and maçã in yellow where the rest of the line is standard white. The code I have is:
SETLOCAL EnableDelayedExpansion
for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (
set "DEL=%%a"
)
call :colorEcho 0e "Jäger bomb"
echo Jäger bomb
call :colorEcho 0e "maçã"
echo maçã
pause
exit
:colorEcho
echo off
<nul set /p ".=%DEL%" > "%~2"
findstr /v /a:%1 /R "^$" "%~2" nul
del "%~2" > nul 2>&1i
The issue is that when it outputs it outputs as "J,,ger" and gives an error saying "FINDSTR: Cannot open maøa". But using the standard echo command both print fine. What's causing this and how do I fix it? Any help is much appreciated!
回答1:
You need add at the begin of the batch script the chcp command telling the codepage of the encoding of your script file.
If you save your script on utf-8 add: chcp 65001 > nul
If you save your script on ansi add: chcp 1252 > nul
All this is needed for cmd for interpret the extended characters of the batch file using the declared codepage instead the system codepage.
(save the next script with notepad++) :
It produces:
@Echo Off
::This script file is encoded using utf-8
chcp 65001 >nul
::
::Call :Color A "######" \n E "" C " 23 " E "!" \n B "#&calc" \n
Call :Color 0e "Jäger bomb" \n
call :Color 0e "maçã" \n
Pause >Nul
Exit /B
:Color
:: v23c
:: Arguments: hexColor text [\n] ...
:: \n -> newline ... -> repeat
:: Supported in windows XP, 7, 8.
:: This version works using Cmd /U
:: In XP extended ascii characters are printed as dots.
:: For print quotes, use empty text.
SetLocal EnableExtensions EnableDelayedExpansion
Subst `: "!Temp!" >Nul &`: &Cd \
SetLocal DisableDelayedExpansion
Echo(|(Pause >Nul &Findstr "^" >`)
Cmd /A /D /C Set /P "=." >>` <Nul
For /F %%# In (
'"Prompt $H &For %%_ In (_) Do Rem"') Do (
Cmd /A /D /C Set /P "=%%# %%#" <Nul >`.1
Copy /Y `.1 /B + `.1 /B + `.1 /B `.3 /B >Nul
Copy /Y `.1 /B + `.1 /B + `.3 /B `.5 /B >Nul
Copy /Y `.1 /B + `.1 /B + `.5 /B `.7 /B >Nul
)
:__Color
Set "Text=%~2"
If Not Defined Text (Set Text=^")
SetLocal EnableDelayedExpansion
For %%_ In ("&" "|" ">" "<"
) Do Set "Text=!Text:%%~_=^%%~_!"
Set /P "LF=" <` &Set "LF=!LF:~0,1!"
For %%# in ("!LF!") Do For %%_ In (
\ / :) Do Set "Text=!Text:%%_=%%~#%%_%%~#!"
For /F delims^=^ eol^= %%# in ("!Text!") Do (
If #==#! EndLocal
If \==%%# (Findstr /A:%~1 . \` Nul
Type `.3) Else If /==%%# (Findstr /A:%~1 . /.\` Nul
Type `.5) Else (Cmd /A /D /C Echo %%#\..\`>`.dat
Findstr /F:`.dat /A:%~1 .
Type `.7))
If "\n"=="%~3" (Shift
Echo()
Shift
Shift
If ""=="%~1" Del ` `.1 `.3 `.5 `.7 `.dat &Goto :Eof
Goto :__Color
回答2:
The error is a result of a limitation of the FINDSTR command, as described at https://stackoverflow.com/a/8844873/1012053. Here is the relevant portion of the extensive answer, with the most important bits in bold italics
Character limits for command line parameters - Extended ASCII transformation
The null character (0x00) cannot appear in any string on the command line. Any other single byte character can appear in the string (0x01 - 0xFF). However, FINDSTR converts many extended ASCII characters it finds within command line parameters into other characters. This has a major impact in two ways:
1) Many extended ASCII characters will not match themselves if used as a search string on the command line. This limitation is the same for literal and regex searches. If a search string must contain extended ASCII, then the
/G:FILEoption should be used instead.2) FINDSTR may fail to find a file if the name contains extended ASCII characters and the file name is specified on the command line. If a file to be searched contains extended ASCII in the name, then the
/F:FILEoption should be used instead.
So the problem can be solved by writing the name of the file to a file and using the /F:file option.
Note there is no need to write a new file with the backspace character for every call. You can use a constant file named @ if you treat your string as a folder, and then append \..\@. Your @ file content should contain 6 backspace characters to get back to the desired string.
The file paths cannot be quoted within the "files.txt" file. This could cause a problem if your string contains a poison character like &. So I store the string in a variable within quotes, and then write using delayed expansion without quotes to preserve the poison character.
@echo off
setlocal EnableDelayedExpansion
for /F "tokens=1,2 delims=#" %%a in (
'"prompt #$H#$E# & echo on & for %%b in (1) do rem"'
) do (
set "DEL=%%a"
)
<nul set /p ".=%DEL%%DEL%%DEL%%DEL%%DEL%%DEL%" > "@"
call :colorEcho 0e "Jäger bomb"
echo(
call :colorEcho 0e "maçã"
echo(
call :colorEcho 0e "this & that"
echo(
pause
exit /b
:colorEcho
setlocal
set "str=%~2"
>files.txt echo !str!\..\@
findstr /v /a:%1 /f:files.txt /r "^$"
This code solves your immediate problem, but the code is still not very robust. Without too much thought, I know of 3 things that will cause it to fail
\anywhere in the string/anywhere in the string:in the 2nd position
I'm sure there are many other potential problems.
You can find much more robust code at How to have multiple colors in a Windows batch file?.
Look at all the answers, as there are many variations on the theme.
You can choose your favorite :-)
来源:https://stackoverflow.com/questions/49307854/cant-get-the-%c3%a4-%c3%a7-or-%c3%a3-to-print-correctly-using-colorecho-in-batch