Wie prüfe ich, ob der Inhalt einer Variablen numerisch ist? - Seite 4

 
Alain Verleyen:
Sie mögen es wirklich kompliziert. Wenn das Ziel ist, nur reelle Zahlen zu verarbeiten, verwenden Sie StringToDouble() und eine Verarbeitung des Spezialfalls 0.

Das war die ursprüngliche Lösung:

honest_knave:

Wenn Sie nicht erwarten, dass der Wert jemals 0 sein wird, wandeln Sie die Zeichenkette in einen Double um und testen Sie, dass er nicht gleich 0 ist.

Der Auftraggeber wollte jedoch in der Lage sein, zu unterscheiden, ob 0 der eingegebene Wert war oder ob 0 das Ergebnis der Zeichenkette als ungültige Zahl war. Sowohl "0" als auch "sfdlgkjsflkjdsklfsd" ergeben mit StringToDouble() oder (double) den Wert 0.

Dies war für den Auftraggeber inakzeptabel und hat zu dieser Diskussion geführt.

 
honest_knave:

Das war die ursprüngliche Lösung:

Der Auftraggeber wollte jedoch in der Lage sein zu unterscheiden, ob 0 der eingegebene Wert war oder ob 0 das Ergebnis einer ungültigen Zahl in der Zeichenkette war. Sowohl "0" als auch "sfdlgkjsflkjdsklfsd" ergeben mit StringToDouble() oder (double) den Wert 0.

Dies war für den Auftraggeber inakzeptabel und hat zu dieser Diskussion geführt.

Deshalb sagte ich "und eine Verarbeitung des Sonderfalls 0".

Vereinfachtes Beispiel:
   double value=StringToDouble(inputs);
   if(value==0)
     {
      if(inputs=="0" || inputs=="0.0")
        {
         //--- all is ok                
        }
      else
        {
         //--- wrong inputs
        }
     }
 
Alain Verleyen:
Deshalb sagte ich "und eine Verarbeitung des Sonderfalls 0".

Vereinfachtes Beispiel :
   double value=StringToDouble(inputs);
   if(value==0)
     {
      if(inputs=="0" || inputs=="0.0")
        {
         //--- all is ok                
        }
      else
        {
         //--- wrong inputs
        }
     }

Und was ist mit 0,00?

Oder +0,00?

Oder .0?


honest_knave:

Ja, das ist ein Problem.

Sie könnten einen String-Vergleich durchführen, wenn der gecastete Wert = 0 ist

d.h. if(cast_value == 0 && str_value == "0")

Aber Sie müssten sich überlegen, ob 0,0 oder 0,00 eingegeben werden soll.

Sie könnten die Zeichenkette in ein Zeichenarray zerlegen und jedes Zeichen testen.

Das hängt davon ab, wie wichtig das ist.

 
honest_knave:

Und was ist mit 0,00?

Oder +0,00?

Oder .0?


Deshalb habe ich "Vereinfachtes Beispiel" gesagt. Ich werde die Aufgabe nicht für den OP erledigen.

 
Alain Verleyen:
Deshalb habe ich "Vereinfachtes Beispiel" gesagt. Ich werde die Aufgabe nicht für den OP übernehmen.

Es ist dennoch eine interessante Übung, d.h. ist es besser, eine Liste möglicher Varianten von "0" zu haben oder einfach alles zu testen?

Ersteres ist wohl schneller, birgt aber das Risiko, dass eine legitime Variante übersehen wird.

Wie wichtig ist jedoch die Geschwindigkeit, wenn es nur bei einemCHARTEVENT_OBJECT_ENDEDIT getestet werden soll?

Wie dem auch sei, ich bin sicher, dass der OP jetzt eine Menge zu tun hat!

 
honest_knave:

Es ist dennoch eine interessante Übung, d.h. ist es besser, eine Liste möglicher Varianten von "0" zu haben oder einfach alles zu testen?

Ersteres ist wohl schneller, birgt aber das Risiko, dass eine legitime Variante übersehen wird.

Wie wichtig ist jedoch die Geschwindigkeit, wenn es nur bei einemCHARTEVENT_OBJECT_ENDEDIT getestet werden soll?

Wie dem auch sei, ich bin sicher, dass der Auftraggeber jetzt eine Menge zu tun hat!

Sie könnten auch verlangen, dass Null als "0" eingegeben wird und alle anderen Fälle abgelehnt werden.

Oder einen regulären Ausdruck verwenden :-D
 
Alain Verleyen:
Sie könnten auch verlangen, dass Null als "0" eingegeben wird und alle anderen Fälle abgelehnt werden.

Oder einen regulären Ausdruck verwenden :-D

Ich persönlich würde wie folgt vorgehen:

Sobald ENDEDIT passiert, wandle ich den OBJ_TEXT in einen Double um und schiebe ihn dann als String zurück in das Eingabefeld (mit StringFormat(), wenn ich das Format kontrollieren möchte). Der Benutzer sieht sofort das Ergebnis seiner Aktionen und kann es entweder ändern, wenn es nicht seinen Bedürfnissen entspricht, oder es lassen.

z.B..

#property strict

#define EDIT_BOX "EditBox"

int OnInit()
  {
   ObjectCreate    (0, EDIT_BOX, OBJ_EDIT000);
   ObjectSetInteger(0, EDIT_BOX, OBJPROP_XDISTANCE200);
   ObjectSetInteger(0, EDIT_BOX, OBJPROP_YDISTANCE200);
   ObjectSetInteger(0, EDIT_BOX, OBJPROP_XSIZE100);
   ObjectSetInteger(0, EDIT_BOX, OBJPROP_YSIZE,  20);
   ObjectSetInteger(0, EDIT_BOX, OBJPROP_ALIGNALIGN_CENTER);
   ObjectSetString (0, EDIT_BOX, OBJPROP_TEXT"Enter Value");
   return(INIT_SUCCEEDED);
  }

void OnDeinit(const int reason)
  {
   ObjectDelete(0, EDIT_BOX);
  }

void OnChartEvent(const int id, const long& lparam, const double& dparam, const string& sparam)
  {
   if(id==CHARTEVENT_OBJECT_ENDEDIT && sparam==EDIT_BOX)
     {
      double value = (double) ObjectGetString(0, EDIT_BOX, OBJPROP_TEXT);
      ObjectSetString(0, EDIT_BOX, OBJPROP_TEXT, (string)value);
     }
  }
 
honest_knave:

Ich persönlich würde wie folgt vorgehen:

Sobald ENDEDIT passiert, wandle ich den OBJ_TEXT in einen Double um und schiebe ihn dann als String zurück in das Eingabefeld (mit StringFormat(), wenn ich das Format kontrollieren möchte). Der Benutzer sieht sofort das Ergebnis seiner Aktionen und kann es entweder ändern, wenn es nicht seinen Bedürfnissen entspricht, oder es lassen.

z.B..

#property strict

#define EDIT_BOX "EditBox"

int OnInit()
  {
   ObjectCreate    (0, EDIT_BOX, OBJ_EDIT000);
   ObjectSetInteger(0, EDIT_BOX, OBJPROP_XDISTANCE200);
   ObjectSetInteger(0, EDIT_BOX, OBJPROP_YDISTANCE200);
   ObjectSetInteger(0, EDIT_BOX, OBJPROP_XSIZE100);
   ObjectSetInteger(0, EDIT_BOX, OBJPROP_YSIZE,  20);
   ObjectSetInteger(0, EDIT_BOX, OBJPROP_ALIGNALIGN_CENTER);
   ObjectSetString (0, EDIT_BOX, OBJPROP_TEXT"Enter Value");
   return(INIT_SUCCEEDED);
  }

void OnDeinit(const int reason)
  {
   ObjectDelete(0, EDIT_BOX);
  }

void OnChartEvent(const int id, const long& lparam, const double& dparam, const string& sparam)
  {
   if(id==CHARTEVENT_OBJECT_ENDEDIT && sparam==EDIT_BOX)
     {
      double value = (double) ObjectGetString(0, EDIT_BOX, OBJPROP_TEXT);
      ObjectSetString(0, EDIT_BOX, OBJPROP_TEXT, (string)value);
     }
  }

Sie brauchen eine Möglichkeit, Ihre Eingaben zu validieren. (eine zusätzliche Schaltfläche ?)

Halten Sie es einfach. Wie auch immer, wie Sie wünschen :p

 
Alain Verleyen:

Sie benötigen eine Möglichkeit, Ihre Eingaben zu validieren. (eine zusätzliche Schaltfläche?)

Ich bin mir nicht sicher, ob ich folgen kann...?

Vielleicht habe ich die Absicht des Auftraggebers missverstanden, aber ich glaube, dass die Schnittstelle dynamisch sein wird, d.h. eine Änderung in diesem Eingabefeld wird zu einer entsprechenden Aktualisierung eines anderen Feldes führen.

Man könnte eine Validierungsschaltfläche einbauen, aber wenn das Ergebnis einfach nur angezeigt wird (und keine Aktion erfolgt), könnte dies ein unnötiger Zusatz sein. Ich bin mir aber nicht sicher - das müsste der Auftraggeber klären.

Alain Verleyen:

Halten Sie es einfach. Wie auch immer, wie Sie wollen :p

Ich bin sehr damit einverstanden, die Dinge einfach zu halten. Geht es noch einfacher als das?

      double value = (double) ObjectGetString(0, EDIT_BOX, OBJPROP_TEXT);
      ObjectSetString(0, EDIT_BOX, OBJPROP_TEXT, (string)value);

PS: Ich bin mir nicht sicher, ob es so ist, wie ich es mir wünsche. Für mich ist es nur eine akademische Diskussion - ich habe keinen Bedarf daran!

 
honest_knave:

Ich bin nicht sicher, ob ich Ihnen folgen kann...?

...
Ehrlich gesagt habe ich keine Ahnung, was der OP beabsichtigt
Wenn wir es als allgemeine Anfrage verstehen: "Wie kann man prüfen, ob der Inhalt einer Variablen numerisch ist?", ist die eleganteste Lösung die Verwendung eines regulären Ausdrucks.