Generate Any Control Character

ASCII has 33 control characters. Many of them are defunct or are used for purposes for which they were not originally intended. Most of them are unprintable and some can cause problems if not filtered out of input. All the same, a handful of these characters have proven to be indispensible when it comes to performing certain tasks in Batch.

In this post, I’ll show you commonly-used techniques for generating specific control characters, as well as two lesser-known methods for storing almost any control character in a variable. But finding uses for them is an entirely different matter. One which will be covered in an upcoming post.

The Null Character

In Batch, there’s no way of storing the Null Character (ASCII 0, NUL) in a variable. But you can create a one-byte file consisting of a single null character by entering the command below:

fsutil file createnew nul.tmp 1

Note that nul.tmp will be created in the current directory. Also, in some versions of Windows, the fsutil command can only be executed by the administrator. In which case, you’ll have to execute the fsutil command above from a Command Prompt running with administrator privileges.

Backspace and Escape

The prompt command supports “dollar escapes” (eg, prompt $a places an ampersand (&) in the prompt, prompt $g outputs a greater-than (>), and so on). Type prompt /? for the full list.

Two of these dollar escapes happen to be control characters: Backspace (ASCII 8, BS); and Escape (ASCII 27, ESC).

The code to capture BS in a variable is explained in this DosTips topic, but here it is in a nutshell:

for /f %%a in ('""prompt $h&for %%b in (1) do rem""') do set bs=%%a
echo(no %bs%visible %bs%spaces

Simply replace prompt $h with prompt $e if you want Escape.

Line Feed

Line Feed (ASCII 10, LF) is the easiest control character to store in a variable. Simply do this:

(set lf=^

)

and you’re done! Just remember to leave the second line blank.

Form Feed

Batch expert Dave Benham recently discovered that the cls command emits a Form Feed (ASCII 12, FF) character. Storing it in a variable is simply a matter of:

for /f %%f in ('cls') do set ff=%%f

Carriage Return

Carriage Return (ASCII 13, CR) can be stored in a variable by using the following code snippet:

for /f %%c in ('copy /z ""%~dpf0"" nul') do set cr=%%c

But how anyone ever figured that out, I’ll never know! 😈 Anyways, please note that due to the way cmd parses input, CR can only be used when delayed expansion is enabled.

Control Z

The conventional way of storing Control Z (ASCII 26, SUB) in a variable is to create an empty file using copy /a which appends Ctrl-Z to the end of the file. And then pass the file to a for /f loop so its contents can be set to a variable. All of which looks something like:

copy nul sub.tmp /a >nul
for /f %%s in (sub.tmp) do set sub=%%s
del sub.tmp

I say “conventional” because there are newer techniques (outlined below) for achieving the same thing that do not require a temporary file.

Numeric Keypad

Most text editors allow you to insert any control character from the Numeric Keypad. For instance, to enter a null character:

  1. Make sure Num Lock is on.
  2. Hold down the Alt key.
  3. Type 256 on the Numeric Keypad.

You can also use this procedure to enter characters such as Bell (ASCII 7, BEL). Remember to type three digits for every character. For instance, Bell would be <Alt+007>.

Command Prompt

Control characters can be typed in manually from the Command Prompt by holding down the Control key and pressing the letter corresponding to their ASCII value.

For instance, pressing <Ctrl+G> would output Bell because Bell is ASCII 7 and G is the seventh letter of the alphabet (see this ASCII table for the full list of keystrokes). Try it for yourself by typing this command:

echo <Ctrl+G>

You should hear a short beep when you press <Enter>.

This works from the command line, but how do you save it to a file? No problem! Just redirect command line output to a file called bel.cmd:

>bel.cmd echo(set ""bel=<Ctrl+G>""

Now you can edit bel.cmd and output the %bel% variable whenever you want to make the computer beep.

Btw, typing <Ctrl+@> from the Command Prompt is supposed to output a null character, but I could never get it to work.

Hybrid Script

A hybrid script can be used to store any control character in a variable except Nul, LF and CR.

The example below (modified from an answer on Stack Overflow) shows how to generate a Horizontal Tab (ASCII 9, HT). The "delims=" is necessary when capturing a tab because for /f uses tab and space as default delimiters.

@if (@X)==(@Y) @goto dummy @end /*
@echo off & setlocal enableextensions

for /f ""delims="" %%t in ('cscript //e:jscript //nologo ""%~dpf0""') do set tab=%%t
echo(words%tab%separated%tab%by%tab%tabs

endlocal & exit /b 0 */
WScript.Echo(""\x09"");

Please note that the argument to WScript.Echo() must be given in hexadecimal. For example, the hexadecimal for Escape (ASCII 27, ESC) would be "\x1b".

The forfiles Exploit

Another method of generating and storing any control character in a variable (apart from NUL, LF, and CR) is to exploit a feature of the forfiles command. The code to obtain Control Z (ASCII 26, SUB), for instance, should go a little something like this:

for /f %%s in (
'forfiles /p ""."" /m ""%~nx0"" /c ""cmd /c echo(0x1a""'
) do set sub=%%s

The problem with forfiles is that it doesn’t ship with all versions of Windows. However, if it’s not on your system, you might be lucky and find a link to a download floating around on the web somewhere. 😉

Conclusion

And this concludes the round-up of all the ways I know of generating control characters and how to store them in variables. If I’ve left anything out, or if you’d like to give me your feedback, please leave a comment.

Advertisements

3 Responses to “Generate Any Control Character”

  1. Sponge Belly

    Hi Jvone!

    Thanks for commenting. This post is out of date. Things have moved on in Batch. Please read the Create NUL and All ASCII Characters Using Only Batch topic on DosTips.com. It contains code that creates one-byte files of all ASCII characters except NUL. And to do that, do the following:

    setlocal enableextensions disabledelayedexpansion
    (set lf=^
    
    )
    
    cmd /d /u /c echo(| (Pause >nul & pause >nul & findstr "^" >lfnull.tmp)
    findstr /v ^%lf%%lf% lfnull.tmp >null.tmp
    del lfnull.tmp
    
    endlocal & exit /b 0

    And that should do it! Let me know if you have any problems.

    – SB

  2. jvone

    The write file command is : “filename set /p “=%var%”

  3. jvone

    Good and thank. I am trying to write a 1 byte file file each ascii from 0 to 255. I am successfully from 0 – 8 by command filename set /p “=%var% However, when set var=[TAB] or FF or LF or ESC … it fail. Do you have any solution ?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s