Unter Berücksichtigung des folgenden Codes
%Vor% Wenn der Benutzer [1 2 3]
eingibt, wird der Variable x
dieser numerische Vektor zugewiesen. Wenn sie {1, [2 3], 'abc'}
eingeben, wird die Variable x
in ähnlicher Weise ein Zellenarray sein, das diese Werte enthält. Gut.
Wenn der Benutzer nun Dies kann zu Problemen führen. Was passiert beispielsweise, wenn der Benutzer Eine weitere potentielle Quelle von Problemen ist das [...] Um Ausdrücke auszuwerten, greift Wenn beispielsweise der Benutzer Dieses Verhalten ist wahrscheinlich von Entwurf. Benutzer eines Matlab-Programms sind vertrauenswürdig, wenn sie Daten eingeben, ähnlich wie vertrauenswürdig, wenn sie nicht Control - C drücken, um das Programm anzuhalten (und dann alle Befehle auszuführen oder alle Variablen zu inspizieren) sie mögen!). Aber in bestimmten Fällen möchte der Programmierer vielleicht eine "sicherere" Also wäre [sqrt(2) sin(pi/3)]
eingibt, wird der Variablen x
die resultierenden Werte zugewiesen: [1.414213562373095 0.866025403784439]
. Dies liegt daran, dass die bereitgestellten Daten von input
: <
input
Eingabeaufforderung für Benutzereingabe.
result = input(prompt)
zeigt die Zeichenfolge prompt
auf dem Bildschirm an und wartet
Für die Eingabe über die Tastatur bewertet alle Ausdrücke in der Eingabe .
und gibt den Wert in result
zurück. [...] addpath('c:\path\to\folder')
als Eingabe eingibt? Da die Eingabe ausgewertet wird, ist es tatsächlich ein
Befehl, der von Matlab ausgeführt wird. So kann der Benutzer einen Pfad zum Pfad hinzufügen. Schlimmer noch, wenn sie path('')
eingeben, wird der Pfad effektiv in nichts geändert, und Matlab hört auf, ordnungsgemäß zu funktionieren.
input
auf Variablen im aktuellen Arbeitsbereich zu . fprintf(1,'%f', varname)
und varname
ein vorhandenes numerisches Array eingibt, kennt der Benutzer den aktuellen Wert. input
Funktion haben, mit der ich meine
[1 2]
eine gültige Eingabe, aber [sqrt(2) sin(pi/3)]
oder path''
würde nicht wegen der 1; und [1 2 3 varname(1)]
würde auch wegen Punkt 2 ungültig sein.
Ich habe eine nicht sehr zufriedenstellende Lösung gefunden (und ich würde gerne über eine bessere lesen). Es verwendet eine semi-dokumentierte -Funktion und impliziert das Speichern der Benutzereingaben in einer temporären Datei . Die Funktion, auf die in Yair Altmans Blog verwiesen wird, ist getcallinfo
. Laut help getcallinfo
:
getcallinfo
Gibt aufgerufene Funktionen und ihre erste und letzte Zeile zurück Diese Funktion wird nicht unterstützt und kann ohne oder ohne entfernt werden Hinweis in einer zukünftigen Version.
Diese Funktion löst Problem 1 (Funktionsaufrufe verhindern). Wie für Problem 2 (Verhindern des Zugriffs auf Variablen) würde es ausreichen, die Eingabe innerhalb einer Funktion zu bewerten, so dass sie andere Variablen nicht sehen kann. Anscheinend (siehe Beispiel 2 unten) erkennt getcallinfo
nicht nur die aufgerufenen Funktionen, sondern auch Variablen . Wie auch immer, es ist wahrscheinlich eine gute Idee, die Auswertung im isolierten Bereich einer Funktion durchzuführen.
Die Prozedur ist dann:
Verwenden Sie die Zeichenfolgenversion von input
, um eine Auswertung zu verhindern:
Speichern Sie die Zeichenfolge in einer Datei:
%Vor% Überprüfen Sie die Eingabezeichenfolge mit getcallinfo
, um mögliche Funktionsaufrufe zu erkennen:
wobei evalinput
die folgende Funktion ist
Betrachten Sie
%Vor%mit Benutzereingabe
%Vor%Dann
%Vor% erzeugt ein nicht-leeres gci.calls.fcnCalls.names
,
sagt uns, dass die Benutzereingabe die Funktionen sqrt
, sin
und pi
aufrufen würde, wenn sie ausgewertet würden. Beachten Sie, dass Operatoren wie /
nicht als Funktionen erkannt werden.
Der Benutzer gibt
ein %Vor%Dann
%Vor%erzeugt
%Vor% So werden Variablen von getcallinfo
erkannt, als wären sie Funktionen.
Wenn ich Ihre Frage richtig verstanden habe, ist es möglich, reguläre Ausdrücke zu verwenden, um das zu erreichen, was Sie versuchen zu tun.
Keine Funktions- oder Variablenaufrufe
Im einfachsten Fall wird überprüft, ob in der Eingabezeichenfolge alphabetische Zeichen enthalten sind. Der Ausdruck wäre dann für x
mit Eingabe:
Das allein funktioniert für die wenigen Beispiele, die Sie oben geben.
Zulassen einiger Funktionen oder Variablen
Angenommen, Sie möchten, dass der Benutzer auf einige Variablen oder Funktionen zugreifen kann, vielleicht auf einfache trigonometrische Funktionen oder auf pi
oder was haben Sie, dann ist es nicht mehr so einfach. Ich habe mit einem Ausdruck wie unten gespielt:
expr = '(?!cos\(|pi|sin\()[a-zA-Z]+
Aber es tut nicht ganz, was erwartet wird. Es entspricht in(
in sin
. Wenn Sie Regex besser als ich kennen, können Sie das massieren, um richtig zu arbeiten.
Anderenfalls wäre dies eine Alternative:
%Vor%, damit Sie die Zeichenfolgen entfernen, an denen Sie interessiert sind.
Hoffe, das hilft.
Update: Um imaginäre / exp-Werte und Pfade zu ermöglichen
Der neue passende Ausdruck wird
%Vor% Dies ignoriert I / I und E / E (Sie können dies nach Belieben erweitern). Sie können auch eine Zwei-Zeichen-Grenze machen, indem Sie zu \{2,}
wechseln, obwohl ich Personen immer noch ein Zeichen anonyme Funktionen haben kann.
Der andere Teil, der auf Eingabe überprüft wird, lautet:
%Vor% Jetzt können Sie benutzerdefinierte Funktionen ausschließen (Sie können dies immer als ein Array haben und sie durch ein |
verbinden) und Pfade.
Hier sind ein paar Beispiele, die zusammen mit dem Üblichen getestet wurden:
Passt
%Vor%Fehler
%Vor%Tags und Links matlab input user-input