Christoph Schnauß: unerwartetes Leerzeichen

hallo Forum ;-)

ich habe ein unerwartetes Problem mit einem kleinen Perl-Script, das auf Formulareingaben reagiert. Es soll auf die bekannte Art mit if-else prüfen, ob einige Formularfelder ausgefüllt sind, bei korrekter Eingabe alles in einer Datei speichern und bei leer gelassenen Formularfeldern eine Fehlermeldung produzieren, an der das Eingabeformular nochmals unten dranhängt  -  also eigentlich etwas sehr Simples. Mein Script tut das auch alles ganz brav.

Wenn jetzt jemand aber seinen Fehler wiederholt, also bei dem vom Script generierten Formular wieder ein eigentlich gefordertes Eingabenfeld freiläßt, wird das nicht als Fehler erkannt, weil das Script aus mir unverständlichen Gründen sämtliche Eingabenfelder mit einem unsichtbaren Leerzeichen vorbelegt.

Die entsprechenden Codezeilen sehen so aus:
im Eingabeformular (HTML) steht
  <td width="15%>  <b>Name</b></td>
  <td><input type="text" name="name" size="50"></td>
  </tr><tr>
  <td>  Mail:</td>
  <td><input type="text" name="mail" size="50"></td>
  </tr>
und mein Script fragt:
  if (!$cgi->param('name')) {
  print <<ENDE;
  <tr><td><h3>Fehler: Es wurde kein Absendername angegeben</h3>
  Anonyme Eintragungen sind nicht zulässig  ;-)</td>
  </tr></table>
  <form method="post" action="$cgi_url">
  <table width="95%" style="position: absolute; top: 130px; left: 20px;"><tr>
  <td colspan="2"><hr /></td></tr>
  ENDE
   print $cgi->Tr($cgi->td({-width =>'15%',$cgi->b('Name')),
                  $cgi->td({-width =>'85%'},"<input type="text" name="name" size="50" value="",
                  $cgi->param('name'),"">",
                  )),
usw.

Es hängt irgendwo an der Stelle mit der Wertübergabe:
  value="",$cgi->param('name'),""
Das brauche ich aber, falls der Benutzer alles korrekt gemacht hat (es sind mehrere if-Abfragen, die ich hier jetzt nicht alle aufgeschrieben habe, und es könnte ja beispielsweise eine Namensangabe gemacht worden sein, aber was anderes falsch).

Weiß jemand eine Lösung?

Grüße aus Berlin

Christoph S.

  1. Weiß jemand eine Lösung?

    Ich hätte derer zwei:

    Benutze das Modul CGI nicht. Es macht ständig irgend etwas unerwartetes.

    "Strippe": prüfe ob die Variablen nur sowas wie ein leerzeichen enthalten oder besser noch: Suche das erste Leerzeichen und das letzte Leerzeichen in den Variablen und lösche es.... Bei den Benutzereingaben hast Du sonst das Leerzeichen ja auch störenderweise drin.

    MFFG (Mit freundlich- friedfertigem Grinsen)

    fastix®

    --
    Meinereinerselbst ist auf der Suche nach Aufträgen
    1. hallo fastix,

      Benutze das Modul CGI nicht. Es macht ständig irgend etwas unerwartetes.

      Naja, das habe ich nun mit voller Absicht drin, ich habe mich entschlossen, ein paar ziemlich alte Sachen zu "modernisieren". Allerdings hast du recht, wenn ich das CGI-Modul nicht benutze, gibts das "Problem" nicht.

      "Strippe": prüfe ob die Variablen nur sowas wie ein leerzeichen enthalten oder besser noch: Suche das erste Leerzeichen und das letzte Leerzeichen in den Variablen und lösche es...

      Du meinst ungefähr so etwas?
        my $cgi->param{'name'} =~ s/ //g;
      Das ist problematisch, weil ein "Name" ein einzelnes Wort sein oder aus zwei Wörtern mit Leerzeichen dazwischen bestehen kann.

      Bei den Benutzereingaben hast Du sonst das Leerzeichen ja auch störenderweise drin.

      Normalerweise störts mich ja nicht, das heißt, wenn jemand alles richtig macht.

      Grüße aus Berlin

      Christoph S.

      1. Hi Christoph,

        Suche das erste Leerzeichen und das letzte Leerzeichen in den Variablen und lösche es...
        Du meinst ungefähr so etwas?
          my $cgi->param{'name'} =~ s/ //g;

        nein - nur das erste bzw. letzte:

        $cgi->param{'name'} =~ s/^\s+//;
        $cgi->param{'name'} =~ s/\s+$//;

        Viele Grüße
              Michael

        --
        T'Pol: I apologize if I acted inappropriately.
        V'Lar: Not at all. In fact, your bluntness made me reconsider some of my positions. Much as it has now.
        (sh:| fo:} ch:] rl:( br:^ n4:( ie:% mo:) va:| de:/ zu:| fl:( ss:) ls:~ js:|)
        Auch diese Signatur wird an korrekt konfigurierte Browser gzip-komprimiert übertragen.
      2. Moin!

        my $cgi->param{'name'} =~ s/ //g;

        Soweit ich aus meinem letzten blind gehaltenem Perl- Seminar (das ist ein Scherz...) noch weiß ersetzt dies alle Leerzeichen, was keine gute Idee ist.

        Mal überlegen: Zuerst suchen wir am einmal am Textanfang: $str =~ s/^ //;
        und einmal am Textende: $str =~ s/ $//;

        Ich weiss jetzt gar nicht, ob auch dies laufen würde:

        $str =~ s/^ | $//g;

        Wir suchen also am Stringanfang ein Leerzeichen, am Stringende ein solches und das g brauchen wir, damit sich der Regex nicht nach dem ersten Fund zufrieden gibt :)

        Aber laut http://www.fastix.de/test/strip.pl läuft es. Natürlich kannst Du das in einer Funktion verwenden.

        MFFG (Mit freundlich- friedfertigem Grinsen)

        fastix®

        --
        Meinereinerselbst ist auf der Suche nach Aufträgen
        1. hallo fastix,

          Ich probiere nachher noch bissel daran herum, danke erstmal für den Vorschlag. Vorerst habe ich den Hinweis von Struppi erfolgreich umgesetzt, aber bei anderen Scripts werde ich ohne RegExpressions (für andere Aufgaben) eh nicht auskommen.

          Grüße aus Berlin

          Christoph S.

          1. Moin!

            Damit tust Du sicher Recht. Meine Abneigung gegen das Modul CGI resultiert wohl eher daraus, daß ich nur ungern die Kontrolle über meine Ausgaben an etwas abgebe, dessen Reaktion ich nicht vollständig kenne ...

            Mich stört ja schon, wenn in PHP nl2br() mir die Zeilenumbrüche durch <br /> ersetzt, was bei HTML 4.01 natürlich vom Validator verworfen wird.

            Es soll Leute geben, die wissen jetzt mein Sternzeichen. Und das stimmt auch :)

            MFFG (Mit freundlich- friedfertigem Grinsen)

            fastix®

            --
            Meinereinerselbst ist auf der Suche nach Aufträgen
            1. hi,

              Mich stört ja schon, wenn in PHP nl2br() mir die Zeilenumbrüche durch <br /> ersetzt

              Ich habe auch erstmal überlegen müssen, was das CGI-Modul eigentlich von mir verlangt. Als ich begriffen hatte, daß es im Grunde genommen XHTML produzieren möchte, war _das_ kein Problem mehr.

              Grüße aus Berlin

              Christoph S.

    2. Weiß jemand eine Lösung?

      Ich hätte derer zwei:

      Benutze das Modul CGI nicht. Es macht ständig irgend etwas unerwartetes.

      Das ist Quatsch. Ich benutzte das Modul seit Jahren und es macht bei mir nie etwas unerwartetes.

      Der Fehler tauch ja auch in Code auf der von Christoph selber produziert wird.

      Versuch's mal mit:

      CGI::textfield (-name => 'name', -value => '');

      Das klappt bei mir ohne Problem sieht auch besser aus als diese ganzen Strings mit den escpae zeichen und das Kästchen wird automatisch mit dem alten Wert gefüllt.

      Struppi.

  2. ENDE
       print $cgi->Tr($cgi->td({-width =>'15%',$cgi->b('Name')),
                      $cgi->td({-width =>'85%'},

    Hier einfach das einfügen:
    $cgi->textfield(-name => 'name', -size => 50, -value => '')

    Struppi.

    1. Eigentlich muss du auch eine Warnung erhalten, da CGI::param('xxx') bei leeren Textfelder 'undef' ergibt.

      Struppi.

      1. hallo Struppi,

        Eigentlich muss du auch eine Warnung erhalten, da CGI::param('xxx') bei leeren Textfelder 'undef' ergibt.

        Ja, das habe ich auch erwartet, ist aber nicht der Fall.

        Bei deinem Vorschlag oben, die Zeile so zu fassen:
          $cgi->td({-width =>'85%'},$cgi->textfield(-name => 'name', -size => 50, -value => '')),
        kriege ich einen weiteren völlig unerwarteten Fehler (mal abgesehen davon, daß ich für "value" einen Wert vorgeben muß). Die Zahl der schließenden Klammern stimmt plötzlich nicht mehr.

        Ich habe mit etwas Herumprobiererei jetzt folgendes drinstehen:
           print $cgi->Tr($cgi->td({-width =>'15%'},$cgi->b('Name')),
                          $cgi->td({-width =>'85%'},
                          $cgi->input({-name =>'name',
                                       -size =>'50',
                                       -value =>$cgi->param('name')}))),
        Und damit scheint es tatsächlich zu funktionieren. Bloß verstehe ich jetzt nicht, wieso ich so viele schließende runde Klammern brauche, nach meiner Zählung sind es zwei zuviel. Allerdings funktioniert es nur so, und die produzierte Bildschirmausgabe ist valides XHTML.

        Grüße aus Berlin

        Christoph S.

        1. Ich habe mit etwas Herumprobiererei jetzt folgendes drinstehen:
             print $cgi->Tr($cgi->td({-width =>'15%'},$cgi->b('Name')),
                            $cgi->td({-width =>'85%'},
                            $cgi->input({-name =>'name',
                                         -size =>'50',
                                         -value =>$cgi->param('name')}))),

          Das value musst du nicht vorgeben, da CGI die felder automatisch füllt  um das zu verhindern muss man einen zusätzlichen Parameter bemühen (in deinem Fall nicht notwendig)

          $cgi->input(-name =>'name',
          -size =>'50',
          -value => 'Dein wert',
          -override => 1
          )

          Struppi.

          1. hallo Struppi,

            Das value musst du nicht vorgeben, da CGI die felder automatisch füllt

            Jaein. Ich habe hier ja ein sehr einfaches Beispiel vorgegeben, weil es mir erstmal um diese doofe Leerstelle ging  -  wenn ich aber jetzt mit meinen Variablen noch herumarbeite, sie mit anderen Inhalten fülle usw. stimmt das, was automatisch reingeschrieben wird, eventuell nicht mehr. Dann muß ich den value eben doch vorgeben.

            Grüße aus Berlin

            Christoph S.

  3. print $cgi->Tr($cgi->td({-width =>'15%',$cgi->b('Name')),
                      $cgi->td({-width =>'85%'},"<input type="text" name="name" size="50" value="",
                      $cgi->param('name'),"">",
                      )),

    Ich vermute mal auch ein Problem mit den Kommas, da denkt Perl, dass du eine Liste meinst. Ich vermute mal du bist besser bedient mit dem Punkt.

    print $cgi->Tr(
    $cgi->td( {-width =>'15%'}, $cgi->b('Name')), # 1 Zelle
    $cgi->td( {-width =>'85%'},$cgi->textfield( -name => 'name', -value => ''))
    );

    Es hat in deinem Code oben eine geschwiefte Klammer gefehlt.

    Struppi.

    1. hallo Struppi,

      Ich vermute mal auch ein Problem mit den Kommas, da denkt Perl, dass du eine Liste meinst. Ich vermute mal du bist besser bedient mit dem Punkt.

      Du meinst das Semikolon. Das steht im ganzen Script wesentlich weiter unten, meine Tabelle hat ja noch mehr Zeilen, aber die brauchte ich ja nicht alle hier zu posten, sie sehen alle gleich aus.

      Es hat in deinem Code oben eine geschwiefte Klammer gefehlt.

      Im Original auf meiner Platte nicht, allerdings steht noch ein Bild dazwischen, das hab ich für das posting rausgelöscht und dabei aus Versehen auch die schließende geschweifte Klammer erwischt.

      Grüße aus Berlin

      Christoph S.

      1. hallo Struppi,

        Ich vermute mal auch ein Problem mit den Kommas, da denkt Perl, dass du eine Liste meinst. Ich vermute mal du bist besser bedient mit dem Punkt.
        Du meinst das Semikolon. Das steht im ganzen Script wesentlich weiter unten, meine Tabelle hat ja noch mehr Zeilen, aber die brauchte ich ja nicht alle hier zu posten, sie sehen alle gleich aus.

        Nö ich meinte die Kommas:

        print $cgi->Tr($cgi->td({-width =>'15%',$cgi->b('Name')),
        $cgi->td({-width =>'85%'},

        "<input type="text" name="name" size="50" value="",
        $cgi->param('name'),
        "">"
        ,

        hier in dem Abschnitt hast du drei Kommas, die eine Liste abbilden. Du willst aber einen String zusammenfügen. CGI::Tr und td reagieren auf sowas manchmal doch anders als man es sich erhofft, da mit Perl dank referenzen und HASHes viel geht, aber halt nicht alles auf einmal.

        Im klartext, du übergibst CGI::td hier erst eine HASH refrenz und dann eine Liste von Parametern nämlich:

        $_[0] = "<input type="text" name="name" size="50" value=""
        $_[1] = $cgi->param('name')
        $_[2] = "">"

        Ich weiss jetzt aber nciht aus dem Kopf was td() daraus macht. ein punkt als wäre hier sinnvoller gewesen.

        Struppi.

  4. Hallo Christoph,

    Es hängt irgendwo an der Stelle mit der Wertübergabe:
      value="",$cgi->param('name'),""

    äh, ich kann zwar kein perl, aber ist das:

    value="",

    denn richtig? fehlt da nicht ein Rückstrich oder so?

    Weiß jemand eine Lösung?

    natürlich nicht, war nur so'ne Vermutung ;)

    Gruß, Andreas

    1. hallo Andreas;-)

      äh, ich kann zwar kein perl, aber ist das:

      value="",
      denn richtig? fehlt da nicht ein Rückstrich oder so?

      Man siehts an der Nachfrage, daß dir da ein paar PERL-Grundlagen fehlen *g*
      Nein, _diese_ Angabe ist vollkommen korrekt. Der Backslash "maskiert" die nachfolgenden Anführungszeichen vor dem Interpreter, so daß die _zweiten_ befolgt werden können. Der Effekt ist, daß der generierte Code völlig korrekt
        value="..." #natürlich ohne die ...
      enthält.

      war nur so'ne Vermutung ;)

      Macht ja nix. Inzwischen ist das Problem ja behoben, es gibt dafür im Thread zwei unterschiedliche Lösungsansätze, die beide zum Erfolg führen.

      Grüße aus Berlin

      Christoph S.