You've accepted a good answer - please leave it that way. This is supplemental information that may prove useful, if not to you then to others facing the same problem.
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "letequ=a(1 b(2 c(3 d(4 e(5"
:tutq
cls
FOR %%a IN (%letequ%) DO echo %%a
SET "tutnum="
SET /p "tutnum=What is the first letter of your name? "
IF NOT DEFINED tutnum GOTO tutq
FOR %%a IN (%letequ%) DO (
SET letterandnumber=%%a
SET "letter=!letterandnumber:~0,1!"
SET "number=!letterandnumber:~2!"
IF "!number!"=="%tutnum%" (
ECHO The first letter of your name is "!letter!"&pause&GOTO :EOF)
)
GOTO tutq
So - I didn't bother to complete the letter/number set. It should be fairly obvious how to do that.
Note the technique of setting a string-value. That syntax ensures trailing spaces on a line are not included in the value assigned, which can sometimes cause problems. For instance,
SET tutnum=
should clear tutnum out of the environment which means that as far as cmd is concerned, it has a value of nothing but if there are stray (and conveniently invisible) spaces on the end of the line, it would be set to those spaces and if defined tutnum would be true.
SET "tutnum="
would clear tutnum as desired, stray spaces or no.
Setting a variable just before a set /p may seem superfluous, but if the response to a set /p is simply Enter then the variable will remain unchanged - it will not automatically have no value as may be assumed. This technique can be used to assign a default value
set "var=default"
set /p "var=prompt-string"
will leave default assigned to var if the user responds Enter
This could be used like
set "var=default"
set /p "var=prompt-string [%var%]"
To show the user the value that will be used if the user responds Enter
Next item to be examined is the for loops. for can be subject to all kinds of jiggery-pokery, but the basic for is
for %%x in (list of items separated by spaces) do something
where each item in the list in turn is assigned to %%a, so each item in the list leteq is assigned in turn to %%a and %%a adopts the values "a(1" "b(2" "c(3" "d(4" and "e(5", then does something with that value.
In the case of the analyse-the-entry portion of the code, something is
SET letterandnumber=%%a
SET "letter=!letterandnumber:~0,1!"
SET "number=!letterandnumber:~2!"
IF "!number!"=="%tutnum%" (
ECHO The first letter of your name is "!letter!"&pause&GOTO :EOF)
The object here is to substring the value in %%a example: "c(3". We can't do a direct substring of %%a, so we assign %%a's value to letterandnumber and substring that.
The substring syntax is
%var:~m,n%
- If m is >=0, then the start of the substring is the m'th character of
var, starting at "character 0"
- If m is <0, then the start of the substring is the m'th character from the end of
var
- If n is >0, then
n is the length of the substring
- If n is <0, then the end of the substring is the n'th character from the end of
var
- n may be omitted. If omitted, the substring is "from the start position to the end"
% may be ! for delayedexpansion mode
So letter is set to ~0,1 that is, the first character for a length of 1 of letterandnumber and similarly number is set to ~2 - the third letter up to the end of the string.
Since letterandnumber is set within the loop (or in any parenthesised sequence of statements, aka "a block") then it may appear as two separate values. %letterandnumber% refers to the value at the time the block is first encountered and parsed whereas !letterandnumber! refers to the value at run-time as it might be set within the block. The !var! syntax is only valid if a setlocal enabledelayedexpansion command has previously been executed.
The reason is that cmd replaces any %var% with the current value of var, then checks the statement for validity. !var! is not replaced until the block is executed.
The consequence of this sequence is significant and if not understood can lead to some vigorous head-scratching.
Suppose we have (note that close-parentheses ase used, not open)
SET "letequ=a)1 b)2 c)3"
FOR %%a IN (%letequ%) DO echo %%a
This will lead to a syntax error because cmd will first replace leteq with its then-current value and then parse it, so it sees
FOR %%a IN (a)1 b)2 c)3) DO echo %%a
assumes that the first close-parenthesis ends the list and expects a do but finds 1 so it reports the problem.
One way to solve this problem is to escape the misinterpreted ) by preceding it with a caret ^
SET "letequ=a^)1 b^)2 c^)3"
FOR %%a IN (%letequ%) DO echo %%a
cmd now sees FOR %%a IN (a^)1 b^)2 c^)3) DO echo %%a and recognises that ^) means "this parenthesis is data, not part of the command" It's therefore happy with the syntax and proceeds to execute the code.
Another way is this (if delayedexpansion is in effect)
SET "letequ=a)1 b)2 c)3"
FOR %%a IN (!letequ!) DO echo %%a
cmd does not substitute the value until after the command has passed the validity check so no error is raised.
@echo off, I'm assuming this isn't the entire code.