Can't get the ä, ç, or ã to print correctly using colorEcho in batch

不想你离开。 提交于 2019-12-22 12:19:45

问题


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:FILE option 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:FILE option 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!