15 Stimmen

Batch File Eingabevalidierung - Sicherstellen, dass der Benutzer eine ganze Zahl eingegeben hat

Ich experimentiere mit einer Windows-Stapeldatei, um einen einfachen Vorgang auszuführen, bei dem der Benutzer eine nichtnegative ganze Zahl eingeben muss. Ich verwende einfache Batch-Datei-Techniken, um Benutzereingaben zu erhalten:

@ECHO OFF
SET /P UserInput=Please Enter a Number: 

Der Benutzer kann hier jeden beliebigen Text eingeben, daher möchte ich eine Routine hinzufügen, die sicherstellt, dass die vom Benutzer eingegebene Zahl gültig ist. Das heißt... sie eingegeben mindestens ein Zeichen, und jedes Zeichen ist eine Zahl von 0 bis 9. Ich hätte gerne etwas, in das ich die Benutzereingabe einspeisen kann. Am Ende der Routine wäre wie ein Wenn/dann, die verschiedene Anweisungen ausführen würde, je nachdem, ob es tatsächlich eine gültige Zahl war oder nicht.

Ich habe mit Schleifen und Substrings und so experimentiert, aber mein Wissen und Verständnis ist immer noch dünn... so jede Hilfe geschätzt werden würde.

Ich könnte eine ausführbare Datei erstellen, und ich weiß, dass es schönere Methoden als Batch-Dateien gibt, aber zumindest für diese Aufgabe versuche ich, es mit einer Batch-Datei einfach zu halten.

16voto

Joey Punkte 329386

Sie tun dies wahrscheinlich nicht in einer DOS-Batch-Datei. Zumindest ist die Unterstützung für set /p ist für mich unter DOS ein Novum :-)

Sie könnten Teilstrings verwenden. Tatsächlich habe ich einmal einen Parser für eine bestimmte reguläre Sprache auf diese Weise geschrieben, aber es ist umständlich. Der einfachste Weg wäre wahrscheinlich, den Inhalt von %userinput% auf eine andere Variable übertragen, indem Sie set /a . Wenn das Ergebnis wie folgt aussieht 0 müssen Sie prüfen, ob die Eingabe selbst 0 sonst kann man daraus schließen, dass es sich um eine Nicht-Zahl handelt:

@echo off
setlocal enableextensions enabledelayedexpansion
set /p UserInput=Enter a number: 
set /a Test=UserInput
if !Test! EQU 0 (
  if !UserInput! EQU 0 (
    echo Number
  ) else (
    echo Not a number
  )
) else (
  echo Number
)

Dies funktioniert jedoch nur für Zahlen im Bereich von Int32 . Wenn Sie sich nur für eine beliebige Zahl interessieren (möglicherweise auch für eine Fließkommazahl), müssen Sie auf den schleifenbasierten Ansatz zurückgreifen, um sie zu zerlegen.

HINWEIS: Aktualisiert, um das Platzproblem zu lösen. Allerdings gibt es immer noch ein Problem, das lauert: Die Eingabe von 123/5 ergibt "Zahl", da set /a kann dies bewerten ...

1 Stimmen

Dies funktioniert nicht, wenn die Benutzereingabe z. B. 123dd lautet. Da steht "Zahl". Es sollte "Keine Zahl" lauten.

1 Stimmen

Wie funktioniert das überhaupt? Ich sehe nur, dass es prüft, ob die Variable gleich 0 ist. Aber ich habe es ausprobiert und es funktioniert - wie?

1 Stimmen

@marky, es gibt zwei verschachtelte Prüfungen. Wenn beide Test y UserInput sont 0 dann ist es offensichtlich eine Zahl, aber ansonsten, wenn Test es 0 y UserInput nicht ist, dann konnte die Eingabe nicht als Zahl analysiert werden und das Ergebnis ist 0, aber das bedeutet, dass die ursprüngliche Eingabe keine Zahl war, um damit zu beginnen.

9voto

Ben Brandt Punkte 2741

Danke an alle. Ich habe versucht, es mir selbst schwerer zu machen, indem ich mir Schleifen und Stringmanipulation angesehen habe. Ich habe Ihre Tipps zur mathematischen Auswertung und zum Vergleich verwendet. Hier ist, was ich schließlich kam mit als mein Konzept Skript:

:Top
@ECHO OFF
ECHO.
ECHO ---------------------------------------
SET /P UserInput=Please Enter a Number: 
ECHO.
ECHO UserInput = %UserInput%
ECHO.
SET /A Evaluated=UserInput
ECHO Math-Evaluated UserInput = %Evaluated%
if %Evaluated% EQU %UserInput% (
    ECHO Integer
    IF %UserInput% GTR 0 ( ECHO Positive )
    IF %UserInput% LSS 0 ( ECHO Negative )
    IF %UserInput% EQU 0 ( ECHO Zero )
    REM - Other Comparison operators for numbers
    REM - LEQ - Less Than or Equal To
    REM - GEQ - Greater Than or Equal To
    REM - NEQ - Not Equal To
) ELSE (
    REM - Non-numbers and decimal numbers get kicked out here
    ECHO Non-Integer
)

GOTO Top

Diese Methode erfasst alle Zahlen und kann erkennen, ob sie positiv, negativ oder Null sind. Jede Dezimalzahl oder Zeichenkette wird als nicht-ganzzahlig erkannt. Der einzige Grenzfall, den ich gefunden habe, ist eine Zeichenkette mit Leerzeichen. Der Text "Number 1" zum Beispiel führt zum Absturz des Skripts, wenn die Benutzereingabe als mathematisch ausgewertet wird. Aber in meiner Situation ist das in Ordnung. Ich möchte nicht, dass mein Skript mit ungültigen Eingaben weiterläuft.

0 Stimmen

Was macht das Ausrufezeichen anders als das Prozentzeichen? Damit bin ich nicht vertraut...

0 Stimmen

Das Ausrufezeichen(!) funktioniert einfach wie der Prozentwert (%) und wird für DELAYED EXPANSION verwendet ... Sie werden wahrscheinlich brauchen: SETLOCAL ENABLEDELAYEDEXPANSION auf, um diese zu verwenden.

0 Stimmen

Funktioniert nicht, wenn Ihre Zahl mit 0 beginnt, da dies als Oktalzahl betrachtet wird und wahrscheinlich fehlschlägt

7voto

Joey Punkte 329386

Sie können auch einen ganz einfachen Trick anwenden:

echo %userinput%|findstr /r /c:"^[0-9][0-9]*$" >nul
if errorlevel 1 (echo not a number) else (echo number)

Diese verwendet findstr Fähigkeiten zum Abgleich regulärer Ausdrücke. Sie sind nicht sehr beeindruckend, aber manchmal nützlich.

0 Stimmen

@levis: Ich zitiere aus der Frage: "Führen Sie eine einfache Operation durch, bei der der Benutzer einen Wert eingeben muss. nicht-negativ Ganzzahlig" (Hervorhebung von mir)

0 Stimmen

Funktioniert gut, imho die BESTE Lösung, aber vergessen Sie nicht, vorher eine Prüfung auf leere Eingaben hinzuzufügen, sonst wird der Errorlevel nicht aktualisiert.

4voto

Wouter van Nifterick Punkte 22981

Dies ist die gleiche Idee wie die von Johannes SET /A setzt einen numerischen Wert. Wenn die Eingabe keine Zahl ist, wird sie auf 0 geändert. Das können Sie hier ausnutzen, um Ihre Prüfung durchzuführen.

@ECHO OFF
SET /P UserInput=Please Enter a Number:
IF %UserInput% EQU 0 GOTO E_INVALIDINPUT

SET /A UserInputVal="%UserInput%"*1
IF %UserInputVal% GTR 0 ECHO UserInput "%UserInputVal%" is a number
IF %UserInputVal% EQU 0 ECHO UserInput "%UserInputVal%" is not a number
GOTO EOF

:E_INVALIDINPUT
ECHO Invalid user input

:EOF

Alternativ können Sie auch eine kleine Javascript-Datei erstellen und diese von Ihrer Batchdatei aus aufrufen. Mit parseInt() können Sie erzwingen, dass die Eingabe eine Ganzzahl ist, oder Sie können Ihre eigene Funktion zum Testen der Eingabe verwenden.

Das Schreiben von Javascript ist genauso schnell wie die Batchdatei, aber es ist viel leistungsfähiger. Keine IDE oder Compiler erforderlich; Notepad genügt. Läuft auf jedem Windows-Rechner, genau wie Ihre Batchdateien. Warum also nicht davon Gebrauch machen?

Sie können sogar Batchdateien und Javascript mischen. Beispiel:

Inhalt von sleep.js:

var SleepSecs=WScript.Arguments.Item(0);
WScript.Sleep(SleepSecs*1000)

Inhalt von sleep.cmd:

cscript /nologo sleep.js %1

Sie können dies nun von einer Batchdatei aus aufrufen, um Ihr Skript für 10 Sekunden schlafen zu lassen. So etwas ist mit einer einfachen Batchdatei nur schwer zu bewerkstelligen.

sleep 10

0 Stimmen

Eine Batch-Schlaf-Funktion: ping -w 1000 -n %1 1.2.3.4 > nul :D

0 Stimmen

Wenn ich zum Beispiel 1c als Benutzereingabe eingebe, erhalte ich die Fehlermeldung --> Ungültige Zahl. Numerische Konstanten sind entweder dezimal (17), hexadezimal (0x11), oder oktal (021). 0 war zu diesem Zeitpunkt unerwartet. Haben Sie das gleiche Problem?

3voto

Mike D Punkte 31

Wie von ghostdog74 bemerkt, funktionieren die Antworten von Joey 26.03.09 (10 Punkte) und Wouter van Nifterick 26.03.09 (5 Punkte) nicht.

Die Antwort von Joey 25. März '10 (Punktzahl 2) funktioniert, außer dass Umleitungssymbole und '&' Syntaxfehler verursachen.

Ich denke, die beste und einfachste Lösung ist die von Sager 8. Oktober '14 (score 0). Leider hat sie einen Tippfehler: ""%a"" sollte ""%a%"" sein.

Hier ist eine Batch-Datei, die auf der Antwort von Sager basiert. Umleitungssymbole und '&' in der Eingabe verursachen keine Probleme. Die einzigen Probleme, die ich finden konnte, wurden durch Zeichenketten verursacht, die doppelte Anführungszeichen enthalten.

@echo off & setlocal enableextensions & echo.
set /p input=Enter a string:
SET "x=" & for /f "delims=0123456789" %%i in ("%input%") do set x=%%i
if defined x (echo Non-numeral: "%x:~0,1%") else (echo No non-numerals)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X