How to Convert Text to Morse Code in a Batch Script
Morse code is a classic method of encoding text characters as standardized sequences of two different signal durations, called "dots" and "dashes". Creating a translator for this is a fantastic exercise in advanced batch scripting, demonstrating string manipulation, array simulation, and character-by-character processing.
This guide will teach you how to build a full text-to-Morse-code converter in a pure batch script. You will learn how to set up an "array" of Morse code values, how to loop through an input string one character at a time, and how to look up and append the correct code for each character.
This is a demonstration of advanced batch scripting logic. For any practical, high-performance encoding task, a more powerful language like Python or PowerShell would be more efficient.
The Core Logic: Character-by-Character Lookup
The cmd.exe interpreter cannot process a whole string at once for this task. We must break the problem down into smaller steps:
- Initialize Data: Create a set of variables that will act as a lookup table or "array," where each variable holds the Morse code for a specific letter or number (e.g.,
morse_A=.-). - Loop Through String: Read the input string one character at a time.
- Lookup: For each character, find the corresponding Morse code in our "array."
- Append: Join the found Morse code to our final result string, adding a space to separate the codes.
The "Array": Storing Morse Codes in Variables
The standard way to simulate an array or a dictionary in a batch script is to create a series of environment variables with a common prefix. To get the Morse code for the letter 'A', we will look up the value of a variable named morse_A.
SET "morse_A=.-"
SET "morse_B=-..."
SET "morse_C=-.-."
... etc.
Example Script: A Full Text-to-Morse-Code Converter
This script is a complete, self-contained solution with all the necessary logic and subroutines.
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
CALL :InitMorseCode
CALL :ConvertToMorse "Hello World" MorseResult
ECHO "Hello World" -> !MorseResult!
CALL :ConvertToMorse "SOS 123" MorseResult
ECHO "SOS 123" -> !MorseResult!
GOTO :EOF
:ConvertToMorse <InputString> <ReturnVar>
SET "Input=%~1"
SET "Output="
REM First, convert the input string to uppercase
CALL :ToUpper Input
:CharLoop
IF DEFINED Input (
REM Get the first character of the input string
SET "Char=!Input:~0,1!"
REM Handle spaces
IF "!Char!"==" " (
SET "Output=!Output! / "
) ELSE (
REM Use indirect expansion to look up the morse code
SET "Code=!morse_!Char!!"
IF DEFINED Code (
SET "Output=!Output!!Code! "
)
)
REM Remove the first character from the input string
SET "Input=!Input:~1!"
GOTO :CharLoop
)
ENDLOCAL & SET "%2=%Output%"
GOTO :EOF
:ToUpper
SETLOCAL ENABLEDELAYEDEXPANSION
SET "StringContents=!%1!"
FOR %%L IN (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) DO (
SET "StringContents=!StringContents:%%L=%%L!"
)
ENDLOCAL & SET "%1=%StringContents%"
GOTO :EOF
:InitMorseCode
SET "morse_A=.-" & SET "morse_B=-..." & SET "morse_C=-.-." & SET "morse_D=-.."
SET "morse_E=." & SET "morse_F=..-." & SET "morse_G=--." & SET "morse_H=...."
SET "morse_I=.." & SET "morse_J=.---" & SET "morse_K=-.-" & SET "morse_L=.-.."
SET "morse_M=--" & SET "morse_N=-." & SET "morse_O=---" & SET "morse_P=.--."
SET "morse_Q=--.-" & SET "morse_R=.-." & SET "morse_S=..." & SET "morse_T=-"
SET "morse_U=..-" & SET "morse_V=...-" & SET "morse_W=.--" & SET "morse_X=-..-"
SET "morse_Y=-.--" & SET "morse_Z=--.."
SET "morse_0=-----" & SET "morse_1=.----" & SET "morse_2=..---" & SET "morse_3=...--"
SET "morse_4=....-" & SET "morse_5=....." & SET "morse_6=-...." & SET "morse_7=--..."
SET "morse_8=---.." & SET "morse_9=----."
GOTO :EOF
How the script works
:InitMorseCode: This subroutine is called once to initialize all themorse_Xvariables that act as our lookup table.:ConvertToMorse: This is the main function.- It first calls
:ToUpperto convert the input string to uppercase, as our lookup table only contains uppercase keys. - It then enters the
:CharLoop, which continues as long as there are characters left in theInputvariable. SET "Char=!Input:~0,1!": Extracts the first character.SET "Code=!morse_!Char!!": This is the indirect expansion trick. If!Char!isA, this line becomesSET "Code=!morse_A!", which then expands to.-. This is how we perform the lookup.SET "Output=!Output!!Code! ": It appends the found code and a space to the result.SET "Input=!Input:~1!": It "consumes" the input string by removing the character we just processed.
- It first calls
ENDLOCAL & SET "%2=%Output%": This is the standard trick to return the finalOutputstring from the subroutine back to the main script.
Common Pitfalls and How to Solve Them
- Performance: This script is an exercise in logic and is very slow for long strings due to the character-by-character
GOTOloop. Solution: For any serious encoding task, a language like PowerShell is orders of magnitude faster. - Special Characters: The script requires
DelayedExpansion, making it vulnerable to input containing!. Punctuation and other symbols are not included in the lookup table and will be ignored. Solution: The script could be expanded to include more characters, but for robust text processing, PowerShell is the better tool. - Case Sensitivity: The lookup is case-sensitive. Solution: The script handles this by converting the entire input string to uppercase before it begins processing.
The Superior PowerShell Alternative
This entire, complex batch script can be replaced by a much shorter and more powerful PowerShell script.
@ECHO OFF
SET "MyText=Hello World"
powershell -Command "$morse = @{'A'='.-'; 'B'='-...'; ... }; -join ('%MyText%'.ToUpper().ToCharArray() | ForEach-Object { $morse[$_] + ' ' })"
This PowerShell one-liner creates a proper hash table (a real dictionary) and processes the string far more efficiently. For any real-world use, this is the correct approach.
Conclusion
Converting text to Morse code is a classic programming exercise that perfectly demonstrates some of the most advanced capabilities, and limitations, of pure batch scripting.
- The solution requires a character-by-character loop.
- Simulated arrays (using variables with a common prefix like
morse_) are used for the lookup table. - Indirect and delayed expansion (
!morse_!Char!!) are the keys to performing the dynamic lookup. - While a fun logical exercise, the pure-batch method is too slow and fragile for practical use with long or complex strings. For those, delegating to PowerShell is the recommended best practice.