2

In a batch file that runs interactively in a Windows Server 2003 command prompt, a SET /p accepts user input into an environmental variable. How do I ensure that the user input is comprised of hexadecimal characters only (i.e., 0123456789ABCDEF)? Input containing any other characters should fail.

For instance:

  • 02A13 should be okay.
  • 3Du*23I should fail.

The logic needs to go like this:

:Get_Hex   
   Set /p _HexVal = Enter hex value:
   If not *ValidHexCheck* Echo Invalid input. Try again.&Goto Get_Hex
:Continue

ValidHexCheck is to be replaced by real code. I can't use FINDSTR for reasons too stupid to get into here. I'm thinking I can do it in a FOR loop. Anyone have nice thoughts?

Tony
  • 2,658
  • 2
  • 31
  • 46

2 Answers2

4

Be careful - you probably don't want a space in your variable name, so you need to remove the space before the = in your SET statement.

One solution is to replace all the hex digits with nothing and see if you have anything remaining.

@echo off
setlocal enableDelayedExpansion
:Get_Hex
set "_HexVal="
set /p _HexVal=Enter hex value:
if not defined _HexVal echo You must enter a value. Try again.&goto Get_Hex
set "test=!_HexVal!"
for %%C in (0 1 2 3 4 5 6 7 8 9 A B C D E F) do if defined test set "test=!test:%%C=!"
if defined test echo Invalid input. Try again.&goto Get_Hex

I also added an additional test to make sure that something was entered. If nothing was entered, then the current value remains. That is why the variable must be cleared before the input statement.

A simpler method is to use FINDSTR to look for a line exclusively containing 1 or more hex digit characters:

@echo off
setlocal enableDelayedExpansion
:Get_Hex
set "_HexVal="
set /p "_HexVal=Enter hex value: "
echo !_HexVal!|findstr /ri "^[0123456789ABCDEF][0123456789ABCDEF]*$" >nul || (
  echo Invalid input. Try again.
  goto Get_Hex
)

Or you could use FINDSTR to look for non-hex digits, but then you must verify there is a value again.

@echo off
setlocal enableDelayedExpansion
:Get_Hex
set "_HexVal="
set /p "_HexVal=Enter hex value: "
if not defined _HexVal echo Invalid input. Try again.&goto Get_Hex
echo !_HexVal!|findstr /ri "[^0123456789ABCDEF]" >nul && (
  echo Invalid input. Try again.
  goto Get_Hex
)

Yet another method is to let FOR /F look for non-hex digits. Again you must also verify there is a value.

@echo off
setlocal enableDelayedExpansion
:Get_Hex
set "_HexVal="
set /p "_HexVal=Enter hex value: "
if not defined _HexVal echo Invalid input. Try again.&goto Get_Hex
for /f "eol=0 delims=0123456789ABCDEFabcdef" %%A in ("!_HexVal!") do (
  echo Invalid input. Try again.
  goto Get_Hex
)
dbenham
  • 127,446
  • 28
  • 251
  • 390
0

One way - replace each hexadecimal character in the input string with "".
If the result is not "" then there was an invalid character;

@echo off
setlocal enabledelayedexpansion
set alphabet=0123456789ABCDEF

set input=DEADBEEF1234  
rem you will need to handle empty input
set test=%input%

for /l %%c in (0,1,15) do (
    if [!test!] neq [] (
        set hexdigit=!alphabet:~%%c,1!
        call set test=%%test:!!hexdigit!!=%%
    )
)

if [%test%] neq [] (
    echo character: %test% in %input% is invalid
    goto :eof
)

echo %input% is valid

For 32bit values (not sure if this is expanded on 64bit)

set input=deadbeef
set test=
set /a test=0x%input% >nul 2>&1
if [%test%] equ [] echo invalid
Alex K.
  • 171,639
  • 30
  • 264
  • 288
  • 1
    I thought of the SET /A test as well. But I discarded it because it will accept input like `1+1`. The arithmetic operators are certainly not valid hex digits :) – dbenham Feb 10 '12 at 18:10
  • Ah yes that a very good point, any of the operators would be accepted – Alex K. Feb 10 '12 at 19:40