jantleman
Goto Top

Batch - Eingabe überprüfen

Hallo Community,
ich beschäftige mich seit einigen Tagen mit Batch und habe beschlossen einen einfachen Sleeptimer zu programmieren. Bis jetzt funktioniet er auch. Das einzige was noch Probleme macht ist: Wenn ich bei der Zeitabfrage statt einer Zahl einen Buchstaben eingebe wird der Buchstabe als 0 interpretiert und der PC fährt sofort runter.

Meine Frage ist jetzt: Ob und wenn ja wie es Möglich ist eine Eingabe zu überprüfen ob es sich dabei um eine Zahl handelt.

Danke für eure Hilfe!

Content-ID: 270948

Url: https://administrator.de/forum/batch-eingabe-ueberpruefen-270948.html

Ausgedruckt am: 23.12.2024 um 18:12 Uhr

njoerg
njoerg 02.05.2015 um 17:34:08 Uhr
Goto Top
Hallo Jantleman,
könnte dieser Lösungsansatz Ihnen weiterhelfen?

:Start
@echo OFF
cls
set /P Eingabe=
if "%Eingabe%" LEQ "99" echo %Eingabe%
if "%Eingabe%" GTR "99" echo Buchstabe
pause
goto :Start

Es wird allerdings nur nach dem ersten Zeichen geschaut. Sowas wie 7a6 wird als Zahl erkannt...

face-smile
rubberman
rubberman 02.05.2015 aktualisiert um 17:41:23 Uhr
Goto Top
Hallo Jantleman,

zB. so:
@echo off &setlocal

set "inp="  
set /p "inp=> "  

:: Die Eingabe soll numerisch sein und zw. 1 und 5 liegen ...
call :check inp 1 5
if errorlevel 1 (echo Fehler!) else echo %inp% ist gueltig.

pause
exit /b


:check VarName Min Max
setlocal EnableDelayedExpansion
:: Test auf Ziffern (keine anderen Zeichen erlaubt).
for /f "delims=1234567890" %%i in ("!%~1!") do (endlocal &exit /b 1)  
:: Test auf gültige Zahl (alles was SET /A fehlerfrei verarbeiten kann).
2>nul set /a "dummy=!%~1!" || (endlocal &exit /b 1)  
:: Test auf Dezimalzahl (keine Oktalzahl durch vorangestellte 0).
if "!%~1!" neq "%dummy%" (endlocal &exit /b 1)  
:: Test auf Minimum
if %dummy% lss %~2 (endlocal &exit /b 1)
:: Test auf Maximum
if %dummy% gtr %~3 (endlocal &exit /b 1)

endlocal &exit /b 0
Grüße
rubberman
Jantleman
Jantleman 02.05.2015 um 20:05:38 Uhr
Goto Top
Hallo rubberman,
Danke für die schnelle Hilfe! Nur leider kenne ich mich mit den Befehlen noch nicht allzu gut aus als dass ich deine Befehlsfolge auf Anhieb verstehe. Ich würde aber gerne das ganze verstehen um mir das in Zukunft auch selber herleiten zu können:
Vielleicht kannst du mir den :check Part etwas genauer erklären. Dafür wäre ich dir sehr dankbar!

Gruß Jantleman
rubberman
rubberman 02.05.2015 um 21:55:21 Uhr
Goto Top
Hallo Jantleman,

das kann ich, obwohl ich es vorgezogen hätte wenn du etwas spezifischer erklärt hättest, wo genau das Verständnisproblem ist. Ein Supportforum ist natürlich kein Tutorial ...

:check VarName Min Max
Das Label heißt :check. Alles was durch ein Leerzeichen davon getrennt ist, gehört nicht mehr dazu. In diesem Fall dienen VarName Min Max dazu dem Benutzer mitzuteilen, dass 3 Argumente übergeben werden sollen.
setlocal EnableDelayedExpansion
Die "verzögerte Variablenerweiterung" wird aktiviert. Das führt dazu, dass Variablen nicht bereits beim Parsen der Codezeilen zum Wert aufgelöst werden, sondern erst beim Ausführen der jeweiligen Codezeile. Bestimmte Zeichen (wie bspw. unpaarige Anführungszeichen) führen auf diese Weise nicht zu einem Syntaxfehler.
Die Syntax für Variablen ändert sich dahingehend, dass umschließende Prozentzeichen als Anführungszeichen geschrieben werden.
Vorab:
Der Kommandozeileninterpreter kann nur ganzzahligen Werte mit einer Breite von 32 Bit (-2147483648 bis 2147483647) als Zahl verarbeiten. Größere, kleinere oder Fließkommawerte, sind nur als Text interpretierbar. Ich betrachte im folgenden aber lediglich positive Werte.
:: Test auf Ziffern (keine anderen Zeichen erlaubt).
for /f "delims=1234567890" %%i in ("!%~1!") do (endlocal &exit /b 1)  
Eine FOR /F Schleife verarbeitet Streams zeilenweise - einen einzeiligen String-Stream in diesem Fall. %~1 ist der 1. übergebene Parameter. Dieser ist der Variablenname. Durch das Einschließen in Ausrufezeichen wird daraus eine Variable, die zum Variablenwert (der Eingabe) aufgelöst wird. Um eine Zeile in einer FOR /F Schleife zu verarbeiten, können Trennzeichen (delims) definiert werden. Diese splitten die Zeile in Teilstrings, wobei die Trennzeichen selbst entfernt werden. Das mache ich mir hier zu Nutze. Besteht die Zeile nur aus den Zeichen 0-9, dann werden alle Zeichen entfernt und der Schleifenrumpf (hinter dem do) wird nicht ausgeführt.
Sollten auch andere Zeichen vorhanden sein, wird der Schleifenrumpf ausgeführt. Dort wird mit endlocal die verzögerte Variablenerweiterung wieder aufgehoben. Mit dem exit /b 1 wird die Subroutine :check verlassen und der Wert 1 zurückgegeben, der im Hauptcode als Errorlevel abrufbar ist.
:: Test auf gültige Zahl (alles was SET /A fehlerfrei verarbeiten kann).
2>nul set /a "dummy=!%~1!" || (endlocal &exit /b 1)  
:: Test auf Dezimalzahl (keine Oktalzahl durch vorangestellte 0).
if "!%~1!" neq "%dummy%" (endlocal &exit /b 1)  
Hier wird ein Textvergleich zwischen dem Eingabewert und dem Wert, der von SET /A berechnet wurde, ausgeführt. Beide sollten gleich sein.
Vorab:
Bis zu diesem Punkt haben wir abgeklärt, dass es sich bei der Eingabe um einen positiven, ganzzahligen Dezimalwert handelt, der sich im gültigen Bereich bewegt. Ab jetzt geht es nur noch darum, ob der definierte Minimal- oder Maximalwert unter- bzw. überschritten wurde.
:: Test auf Minimum
if %dummy% lss %~2 (endlocal &exit /b 1)
%~2 ist der 2. übergebene Parameter. LSS ist der Operator für "kleiner als".
:: Test auf Maximum
if %dummy% gtr %~3 (endlocal &exit /b 1)
%~3 ist der 3. übergebene Parameter. GTR ist der Operator für "größer als".
endlocal &exit /b 0
Wenn die Subroutine nicht vorher wegen eines Fehlers verlassen wurde, geben wir nun mit exit /b 0 den Errorlevel 0 an den Hauptcode zurück und signalisieren damit, dass alles OK war.

Grüße
rubberman
Jantleman
Jantleman 03.05.2015 um 13:30:13 Uhr
Goto Top
Hallo rubberman
VIELEN VIELEN DANK!
entschuldige, dass ich dir so einen Aufwand beschert habe aber jetzt kann ich mir das alles in Zukunft auch selber zusammen basteln weil ich ja jetzt verstehe was jeder einzelne Befehl macht. Danke für die ausführliche erklärung und in Zukunft werde ich genauer beschreiben was ich nicht verstehe.

Gruß Jantleman