1

I'm trying to make a self-building chatbot that learn questions by inputing question and three possible answers, then, it randomize that three answers and give it as output. The learned question goes to the final line of the same batch file.

Here's the sample:

@echo off&&setlocal enabledelayedexpansion
echo/teach me a question to answer.
set/p q=
echo(>>%~f0
echo/:%q: =%>>%~f0
cls
echo/teach me three ways to answer it.
set/p a1=
set/p a2=
set/p a3=
echo/set a[0]=%a1%>>%~f0
echo/set a[1]=%a2%>>%~f0
echo/set a[2]=%a3%>>%~f0
echo/"set/a ax=%random% %%3&&set aa=!a[%ax%]!">>%~f0
echo/"echo %aa%">>%~f0

But I get the following:

:howareyou?
a[0]=good
a[1]=fine
a[2]=well
"set/a ax=24793 %3&&set aa="
"echo "

It's possible to get

set/a ax=%random% %%3&&set aa=!a[%ax%]!
echo %aa%

exactly as it is?

FZs
  • 16,581
  • 13
  • 41
  • 50
G.K.L
  • 25
  • 4

2 Answers2

1

There are two problems in this code.

First of all, to answer your question:

How to echo exactly what I type in?

In batch, the answer is always more complicated than you think. In case of echo, quotes don't really change the way % and ! interpreted, but they are echoed as well, which is bad now.

Instead, escape % by duplicating, & by putting a ^, and ! by putting two ^s before it [ref]:

echo set/a ax=%%random%% %%%% 3^&^&set aa=^^!a[%%ax%%]^^! >>%~f0
echo echo %%aa%% >>%~f0

Now you can see, that everything's echoed correctly, but the echoed code still won't work.

Why?

The second problem is the &&: percent-variables (%var%) will be substituted before the evaluation of the line or the command group (commands enclosed by parentheses).

That is, since the set /a and set are on the same line, %ax%'s value will be substituted before set /a sets it. That could be avoided by using the power of the Delayed Expansion, and its !ax! syntax, but in this case, it isn't possible because it is accessed inside another variable access.

So, instead do what && would do otherwise:

set/a ax=%random% %% 3
if %errorlevel% GTR 0 set aa=^^!a[%%ax%%]^^!

Finally, you end up with something like:

echo set/a ax=%%random%% %%%% 3 >>%~f0
echo if %%errorlevel%% GTR 0 set aa=^^!a[%%ax%%]^^! >>%~f0
echo echo %%aa%% >>%~f0
FZs
  • 16,581
  • 13
  • 41
  • 50
  • Cool!! It worked, thank you. But the string `set aa=!!a[%%ax%%]!!` become `set aa= `. Somehow if it's `set aa=!!!a[%%%ax%%]!!`, works, but if it got symmetrical `%` and `!`, still blank. Do you know why? – G.K.L Mar 26 '20 at 14:59
  • @G.K.L I've corrected my post. Appearently, I've forgotten how `!`s need to be escaped, that's why `!!` doesn't work (it should be `^^!` instead). However, I **have no idea** why the 3-2 variant works... Batch files and their mystic, strange bugs... – FZs Mar 26 '20 at 21:04
0

Take a look Here for a functional example of escaping exclamation marks used in delayed variables for this type of situation.

@echo off & setlocal DisableDelayedExpansion Set "/Ex=^!"

and to utilize:

Echo(Set "Answer=%/Ex%Answer[%%RandAnswer%%]%/Ex%">>Bot.bat

Highly recommend reading here to understand the way the command line is parsed and why this works.

T3RR0R
  • 2,747
  • 3
  • 10
  • 25