$xNeTworKx: grep liefert nicht gewünschtes Ergebnis?

Hallo,
Ich will eine Funktion haben, die mir WAHR zurückgibt, wenn die Eingabe nicht leer ist und nicht von 1 und 31 ist. Bis jetzt habe ich es so gelöst:

if (($$gebtag ne '') && (!grep /$$gebtag/, (1..31)))   {
$$error = 1;
$$gebdatenerror = 'Der Geburtstag ist nicht gültig !';
}

Komischerweise gibt mir die Funktion FALSE zurück, wenn ich 0 eingebe. Wenn ich 32 eingebe, funktioniert es wie es soll. Bei -1 funktioniert es auch richtig, aber warum wird 0 miteinbezogen?
Ich habe auch schon versucht 2..31 anzugeben, aber 1 und 0 liefern auch FALSE zurück. Warum ist das so und wie kann ich es lösen?
P.S Ich könnte naütlich prüfen, ob die Eingabe != 0 ist, aber ich würde lieber wissen, warum 0 bei dieser Funktion miteinbezogen wird.

$xNeTworKx.

--
Mit Computern lösen wir Probleme, die wir ohne sie gar nicht hätten.
  1. Hi,

    so gehts:

    $$gebtag = 32;
    if (($$gebtag ne '') && (!grep /^$$gebtag$/, (1..31)))   {
     $error = 1;
     print "Der Geburtstag ist nicht gültig !";
    }

    Gruß vom Horst

    1. Hallo,
      danke, so klappts, aber irgendwie ist das schon sehr krass, weil warum beinhaltet (1..31) die 0? Das verstehe ich irgendwie nicht ganz?

      $xNeTworKx.

      --
      Mit Computern lösen wir Probleme, die wir ohne sie gar nicht hätten.
      1. also...

        bei der 1.

        Programm vergleicht die 1 mit der Liste. 1 kommt drin vor *yippi*

        bei der 0

        Programm vergleicht mit der 1 = false
                                    2 = false
                                    .
                                    .
                                    10 = true
        ja, die 0 kommt in der 10 vor....

        Gruß vom Horst

        PS: Durch das ^ und $ sagst Du dem Programm, dass das Skalar wirklich
        nicht mehr haben darf, als die Zeichen dazwischen

        1. Hallo,

          Programm vergleicht mit der 1 = false

          2 = false
                                       .
                                       .
                                      10 = true

          ja, die 0 kommt in der 10 vor....

          Ok alles klar :)
          Danke.

          --
          Mit Computern lösen wir Probleme, die wir ohne sie gar nicht hätten.
  2. Hallo,
    Ich will eine Funktion haben, die mir WAHR zurückgibt, wenn die Eingabe nicht leer ist und nicht von 1 und 31 ist. Bis jetzt habe ich es so gelöst:

    if (($$gebtag ne '') && (!grep /$$gebtag/, (1..31)))   {
    $$error = 1;
    $$gebdatenerror = 'Der Geburtstag ist nicht gültig !';
    }

    Warum prüfst du den mit einer Schleife?
    if ( $$gebtag && ($$gebtag < 0 || $$gebtag > 31))  {
     $$error = 1;
    $$gebdatenerror = 'Der Geburtstag ist nicht gültig !';
    }

    Darüberhinaus, würde ich die Gültigkeit eines Datums nicht so prüfen. Du solltest mit localtime und Time::localtime die Zahlen miteinander vergleichen. Dann kannst du wirklich feststellen ob das Datum ein gültiges Datum ist.

    Struppi.

    1. Hallo,

      Warum prüfst du den mit einer Schleife?
      if ( $$gebtag && ($$gebtag < 0 || $$gebtag > 31))  {
      $$error = 1;
      $$gebdatenerror = 'Der Geburtstag ist nicht gültig !';
      }

      Du hast Recht. Das ist effizienter.

      Darüberhinaus, würde ich die Gültigkeit eines Datums nicht so prüfen. Du solltest mit localtime und Time::localtime die Zahlen miteinander vergleichen. Dann kannst du wirklich feststellen ob das Datum ein gültiges Datum ist.

      Das würde ich nicht, weil es ziemlich uneffizient ist, extra wegen der Überprüfung von 3 Zahlen, extra ein Modul zu importieren oder sonst irgendwie zusätzlichen Code schreiben.

      $xNeTworKx.

      --
      Mit Computern lösen wir Probleme, die wir ohne sie gar nicht hätten.
      1. Darüberhinaus, würde ich die Gültigkeit eines Datums nicht so prüfen. Du solltest mit localtime und Time::localtime die Zahlen miteinander vergleichen. Dann kannst du wirklich feststellen ob das Datum ein gültiges Datum ist.

        Das würde ich nicht, weil es ziemlich uneffizient ist, extra wegen der Überprüfung von 3 Zahlen, extra ein Modul zu importieren oder sonst irgendwie zusätzlichen Code schreiben.

        Das ist Quatsch. Time::local ist ein kleines Modul und du unterschätzt die Schnelligkeit von Perl, ich halte es eher für uneffizient stundenlang rumzuprogrammieren und dann das falsche Ergebnis zu erhalten. es geht ja schließlich nicht um die Überprüfung von 3 Zahlen, sondern um die Überprüfung eines Datums was wesentlich komplexer ist.

        Was machen deine Test bei:

        31.4.2003 -> gültig?
        29.2.2000 -> gültig?
        29.2.2003 -> gültig?

        das selber zu machen ist müßig und ineffizient.

        print checkDate(29,2, 2000) ? 'gültig' : 'nicht gültig';
        print "\n";
        print checkDate(29,2, 2001) ? 'gültig' : 'nicht gültig';
        print "\n";

        sub checkDate
        {
            my($t, $m, $j) = @_;
            use Time::Local;
            $m--;
            my $check = timelocal(0, 0, 0, $t, $m, $j);
            my ($t1, $m2, $j2) = (localtime($check))[3..5];
            $j2 += 1900 if($j2 < 1900);
            return ($t == $t1 && $m == $m2 && $j == $j2);
        }

        so geht's.
        Struppi.

        1. Hallo,
          es geht eigentlich um die Überprüfung einer Geburtsdatumseingabe.

          if (($$gebtag ne '') && ($$gebtag < 1 || $$gebtag > 31))   {
          $$error = 1;
          $$gebdatenerror = 'Der Geburtstag ist nicht gültig !';
          }
          if (($$gebmonat ne '') && ($$gebmonat < 1 || $$gebmonat > 12))    {
          $$error = 1;
          $$gebdatenerror = 'Der Geburtsmonat ist nicht gültig !';
          }
          if (($$gebjahr ne '') && ($$gebjahr < 1900))    {
          $$error = 1;
          $$gebdatenerror = 'Der Geburtsjahr ist ziemlich unglaubwürdig !';
          }

          Der User kann doch eingeben was er will. Das hat gar nichts mit dem aktuellen Datum zu tun.
          Der User soll eben nur nicht irgendwelche utopischen Werte wie 45.23.1330 eingeben können.
          Bei Jahr ist klar, dass ich nicht weis Gott wie gut nachprüfen kann, ob er nicht das Jahr 3000 eigegeben hat. Vielleicht werde ich dies noch ändern und das aktuelle Jahr mit time abfragen, und den gültigen Wert zwischen diese beiden Werte 1900 - aktuelles Jahr festlegen.

          $xNeTworKx.

          --
          Mit Computern lösen wir Probleme, die wir ohne sie gar nicht hätten.
          1. Der User kann doch eingeben was er will. Das hat gar nichts mit dem aktuellen Datum zu tun.

            Das sach ich ja auch nicht, sondern mit einem 'gültigen' Datum.

            Der User soll eben nur nicht irgendwelche utopischen Werte wie 45.23.1330 eingeben können.

            Ich verstehe dich so, das du sagst, mir ist es egal ob das Datum gültig ist, ich überprüfe nur grob.
            d.h. du aktzeptierst den 29.2.2003 weil du der Meiinung bist ein Winzmodul wie Time::Local belastet dein Rechner zu stark?
            Ich hab hier einen AMD K266 und würd nie auf so eine Idee kommen.

            Naja, es ist deine Zeit.
            Ich würde mich aber wirklich an deiner Stelle mehr mit Modulen vertraut machen. Da du am Schluss effiezienter an's Ziel kommst, für die meisten Probleme existieren schon Module.

            Struppi.

            1. Hi,
              achso, jetzt verstehe ich was du meinst. Das ist natürlich etwas anderes. Bin eigentlich nie davon ausgegangen, die Eingabe so genau nach dem Datum zu überprüfen, aber die Überlegung ist gut und werde es wahrscheinlich doch so ändern.

              $xNeTworKx.

              --
              Mit Computern lösen wir Probleme, die wir ohne sie gar nicht hätten.