Formularverwertung: String darf nur 0 und 1 enthalten

  • Hallo,
    ich habe mal eine Frage zur Verarbeitung von HTML-Formularen mit PHP.

    Es geht dabei darum, zu prüfen, ob eine Eingabe nur aus 0-en und 1-en besteht.
    Ich müsste also zuerst prüfen, dass nur ganze Zahlen eingegeben wurden und danach, ob diese jeweils >= 0 und <= 1 sind.

    Wenn ich bspw. die Zahl 00110101 in ein Formularfeld (name='bin') eingebe und das Formular abschicke (method='post'), steht mir die Eingabe unter $_POST['bin'] zur weiteren Verarbeitung zur Verfügung.
    Das Problem ist nur, dass es sich dabei immer um einen String handelt.
    Es würde mir also bspw. nichts bringen, wenn ich prüfe, ob die Eingabe vom Typ Integer ist, um erstmal festzustellen, ob auch nur ganze Zahlen eingegeben wurden.

    Auch die PHP-Funktion is_numeric() hilft mir da nicht weiter, weil bei numeric unter Anderem auch die Hex-Schreibweise erlaubt ist.

    Kann mir vielleicht mal jemand kurz erklären, wie das grundsätzlich funktionieren könnte?

  • Wieso prüfst nicht in einer Schleife alle Zeichen auf 0 und 1?

    Stimmt!
    Ich werde also einfach eine for - Schleife erstellen, die für die Stringpositionen 1 bis 8 jeweils prüft, ob diese 0 oder 1 sind.
    Wenn ja, dann muss nichts getan werden. Wenn nein, dann muss eine Fehlermeldung kommen.

    Ich müsste also lediglich eine Sache wissen: Wie spricht man eine bestimmte Position/Stelle in einem String an, bspw. die 3 Stelle. Und wierum zählt PHP dabei (von hinten oder von vorn?).


    @Paulchen und michi204: Es ist zwar schön, dass ihr gleich so konkret antwortet, aber mir ist mit einer Erklärung ohne Code trotzdem oft besser geholfen, weil ich dann den Sachverhalt an sich verstehe und damit nicht mehr unbedingt an PHP gebunden bin. ;)

  • Ich werde also einfach eine for - Schleife erstellen, die für die Stringpositionen 1 bis 8 jeweils prüft, ob diese 0 oder 1 sind.


    erm ... wozu eine for-Schleife?

    Code
    preg_match('/^[01]{8}$/')

    müsste doch reichen, oder steh ich irgendwie auf der Leitung? Damit ist der String genau 8 Zeichen lang und hat nur 0er und 1er.


    Ich müsste also lediglich eine Sache wissen: Wie spricht man eine bestimmte Position/Stelle in einem String an, bspw. die 3 Stelle. Und wierum zählt PHP dabei (von hinten oder von vorn?).


    meinst Du PHP direkt, oder die RegExps in PHP?

    *** Make it idiot proof, and someone will build a better idiot. ***

  • erm ... wozu eine for-Schleife?

    Code
    preg_match('/^[01]{8}$/')

    müsste doch reichen, oder steh ich irgendwie auf der Leitung?

    Aber preg_match ist doch eine vorgefertigte Funktion und ich verstehe nicht so recht, was diese tut bzw. wie sie es tut.
    Ich würde den Algorithmus gerne komplett selbst programmieren. Deshalb die Schleife.
    Die müsste dann für n=0 bis n=7 (n ist die Stelle im String), jeweils prüfen, ob da 0 oder 1 steht.
    Und wenn 8 mal true zurückgegeben wurde, also da tatsächlich eine Binärzahl steht, gibt meine Funktion check_bin dann auch true zurück. :D

  • Aber preg_match ist doch eine vorgefertigte Funktion und ich verstehe nicht so recht, was diese tut bzw. wie sie es tut.
    Ich würde den Algorithmus gerne komplett selbst programmieren. Deshalb die Schleife.
    Die müsste dann für n=0 bis n=7 (n ist die Stelle im String), jeweils prüfen, ob da 0 oder 1 steht.
    Und wenn 8 mal true zurückgegeben wurde, also da tatsächlich eine Binärzahl steht, gibt meine Funktion check_bin dann auch true zurück. :D

    in der praxis ist preg_match so etwas wie ein solider grundbaustein für php-programme. warum das rad 2 mal erfinden?

    preg_match prüft einfach, ob der inhalt einer variable einen regulären ausdruck erfüllt. falls dir der begriff "regulärer ausdruck" nichts sagt, verstehe ich deine skepsis. in diesem fall würde ich die gelegenheit nutzen, eines der mächtigsten werkzeuge der informatik kennenzulernen.

    lg,
    michi

  • Aber wenn du nur ein einzelnes Zeichen brauchst, genügt auch

    PHP
    $str{4}

    Für das 5. Zeichen.

    Man sollte lieber eckige Klammern benutzen, also z.B.

    PHP
    $str[4]

    für das 5. Zeichen. Geschwungene Klammern funktioniert zwar auch, aber

    Zitat von http://de.php.net/manual/en/language.types.string.php

    (...) using square array-brackets is preferred because the {braces} style is deprecated as of PHP 6.

    Wie du jedenfalls erkennst beginnt PHP bei 0 zu zählen, $str[0] ist also das 1. Zeichen eines Strings. Mer dazu findest du im PHP-Manual zu Strings, lies das doch mal durch.

    Was deine gewünschte Schleife angeht, mit der du das Problem natürlich auch - wenn auch ein bißchen umständlich - lösen kannst:

    PHP
    $ok = true;
    for ($i = 0; $i < strlen($str); $i++) {
      if ($str[$i] != '0' || $str[$i] != '1') {
        $ok = false;
        break;
      }
    }
    
    
    if ($ok) echo 'String ist OK.'; else echo 'String ist nicht OK.';
  • Hallo,

    spinball: Danke, genau das hab ich gesucht.

    michi204: Werde mir preg_match mal genauer anschuauen, wenn das so bedeutend ist.

    Ich poste hier mal den kompletten Code meines kleinen Programms. Das ist dazu da, um 8-Bit Binärzahlen in die Dezimaldarstellung umzuwandeln.

    Die Prüffunktionen scheinen fehlerfrei zu laufen, aber die eigentliche Umrechnung klappt noch nicht. Eventuell habe ich da irgendwo einen Fehler bei den Variablenzuweisungen gemacht.
    Kann da mal jemand schauen.
    Ist sonst nochwas an meinem Code auszusetzen? Bin dankbar für Hinweise.


  • michi204: Werde mir preg_match mal genauer anschuauen, wenn das so bedeutend ist.

    nicht diese eine funktion, sondern reguläre ausdrücke im allgemeinen sind das bedeutende. :)

    Zitat


    Die Prüffunktionen scheinen fehlerfrei zu laufen, aber die eigentliche Umrechnung klappt noch nicht. [...]

    habs jetzt nur überflogen:

    Code
    for ($pos = 7; $pos [COLOR=Red]<[/COLOR]= 0; $pos--) {

    diese zeile wolltest du bestimmt nicht so.

    lg,
    michi

  • Code
    for ($pos = 7; $pos [COLOR=Red]<[/COLOR]= 0; $pos--) {

    diese zeile wolltest du bestimmt nicht so.

    Ja, stimmt. Hab das mal in >= geändert.

    Und wenn man dazu noch nicht mal das Wort return richtig schreiben kann, haut das natürlich nicht hin. :D

    Jetzt bin ich schonmal soweit, dass überhaupt ein Ergebnis geliefert wird. Das ist zwar immer 0. Aber ich hoffe mal, dass ich den entsprechenden Fehler noch finde.

  • ich habe schon länger nicht mehr PHP benutzt, und habe auch keine Möglichkeit den plain code weiter zu überprüfen, daher lasse ich mich gerne korrigieren, aber ... für das was Du machen möchtest, müsste das locker reichen.

    @trim: http://at.php.net/manual/en/function.trim.php
    @preg_match: http://at.php.net/manual/en/function.preg-match.php
    @bindec: http://at.php.net/bindec

    P.S.: Und ja, das regexp Konzept sollte man schon verstehen wenn man Informatiker sein möchte. ;) Im Einzelnen für PHP hier erklärt: http://at.php.net/manual/en/ref.pcre.php

    *** Make it idiot proof, and someone will build a better idiot. ***

  • Und ja, das regexp Konzept sollte man schon verstehen wenn man Informatiker sein möchte. ;)

    Wobei die Idee, einen Binaerstring manuell in Dezimaldarstellung umzuwandeln ja auch nicht die uebelste ist.

    Der Code hat jedenfalls Probleme:

    Du hast hier in der for-Schleife 2 Zuweisungen (also istgleich-Zeichen). Die erste ist OK, die zweite aber ganz falsch. Links vom istgleich-Zeichen darf nur eine Variable stehen.

    Was du meinst ist:

    Code
    $sum = $sum + $ptz;

    Oder auch abgekuerzt:

    Code
    $sum += $ptz;

    Man koennte die 2 Zeilen auch gleich zusammenfassen:

    Der Code sollte jetzt auch mit beliebig langen Eingaben (nicht nur 8 Zeichen) funktionieren, habs aber nicht getestet.

  • ...für das was Du machen möchtest, müsste das locker reichen.

    @trim: http://at.php.net/manual/en/function.trim.php
    @preg_match: http://at.php.net/manual/en/function.preg-match.php
    @bindec: http://at.php.net/bindec

    Das mag stimmen, aber mein Ziel ist es nicht in erster Linie schnell verwertbaren und effizienten Code zu produzieren.
    Ich will verstehen (und selber bestimmen), was passiert, damit ich ein wenig mehr über Algorithmen und Programmierung (spez. Modularisierung) lerne.
    Würde ich da die fertigen Funktionen benutzen, wäre das wohl eher kontraproduktiv.

    beefy: Danke für das Beispiel. Ich werd das erstmal mit den 8 Stellen fertig machen und dann eine Version für beliebig lange Zeichenketten erstellen. Alles der Reihe nach eben... :)
    EDIT: Ich habe jetzt den eigentlichen Fehler in meinem Programm entdeckt.

    Code
    $prod = $input[$pos]*2[color='red'][b]^[/b][/color](7-$pos);

    Anscheinend bedeutet ^ in PHP was anderes als "hoch".

    Ich habe das Problem jetzt erstmal so gelöst:

    PHP
    $prod = $input[$pos]*pow(2 ,(7-$pos));

    Gibt es auch eine Möglichkeit das ohne die Funktion pow() zu machen? Ich müsste nur die korrekte Schreibweise für "a hoch x" wissen.

  • Gibt es auch eine Möglichkeit das ohne die Funktion pow() zu machen? Ich müsste nur die korrekte Schreibweise für "a hoch x" wissen.

    so viel ich weiß nein. ^ ist bitwise-XOR.

    für solche zwecke würde ich mir die offizielle php-doku von php.net herunterladen, wenn du die auf der festplatte hast, kannst du noch schneller was nachsehen (leider ohne die oft guten kommentare).

    lg,
    michi

  • Hallo, ich habe mal noch eine kleine Verbesserung in der Funktion eingebaut, die prüft, ob die Eingabe eine Binärzahl ist.

    Wenn ich die Anführungszeichen weglasse, kann man jedes beliebige Zeichen (außer die Zahlen ungleich 0 und 1) auf der Tatsatur eingeben, ohne, dass eine Fehlermeldung kommt. Diese repräsentieren dann jeweils den Wert 0.
    Das liegt wahrscheinlich daran, dass es sich bei $input[$pos] um eine Zeichenkette und nicht um eine Integer-Variable handelt. Wenn ich die Überprüfung dann aber mit Integer-Werten (also ohne "") durchführe, kommt es dazu, dass auch Buchstaben und Sonderzeichen akzeptiert werden, denn: intval(a) = 0

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!