MatzeA: Zeilenumbruch \n wird nicht ausgegeben.

Servus,

folgende Methode soll mir alle aufrufe in einer Datei eintragen.

sub count {
   my ($page,$ipnum)=@_ ;
   my $checknone = 0;
   my $date= &datum_zeit;
   my $lock = 1;

#Daten laden
   open (DAT , "< ./data/stat.log") || die "Kann Datenfile (/data/stat.log) nicht zum Lesen öffnen" ;
   my @lines = <DAT> ;
   close(DAT) ;

#Count schreiben
   open (DAT , "> ./data/stat.log") || die "Kann Datenfile (/data/stat.log) nicht zum Schreiben öffnen" ;
   flock(DAT,2) if ($lock==1) ;
   foreach (@lines)
      {
         my @poll_set = split(/|/) ;
         if ($poll_set[1] eq $page)
            {
                $poll_set[0]++;
                $checknone = 1;
            }
                print DAT "$poll_set[0]|$poll_set[1]|$poll_set[2]|$poll_set[3]|\n " ;
      }
   close(DAT) ;

if ($checknone == 0)
   {
   #
      open (DAT , ">> ./data/stat.log") || die "Kann Datenfile (/data/stat.log) nicht zum Schreiben öffnen" ;
      flock(DAT,2) if ($lock==1) ;
      print DAT "1|$page|$ipnum|$date|" ;
      print DAT "\n" ;
      close(DAT) ;
   }

}

so sähe es dann aus.

1|spass|127.0.0.1|16.02.2004 : 21:32|
1|bilder|127.0.0.1|16.02.2004 : 21:41|

Das Dumme ist nur, dass das Script nie über 2 Einträge hinaus kommt.
Das Problem liegt daran, dass der letzte Eintrag nie und nimmer einen Zeileumbruch bekommt und somit obige forech Schleife keine zweimal sondern nur einmal durchläuft.

Verdammt was mache ich gedanklich nur falsch?

Gruss Matze

  1. Hi,

    der Fehler ist eigentlich recht simpel:

    |$poll_set[1]|$poll_set[2]|$poll_set[3]|\n " ;

    $poll_set[3] hat, aus deinem Split noch einen Zeilenumbruch an letzer Stelle. Das kannst du entweder durch bessere formulierung deines splits beheben, oder einfacher durch ein chomp($poll_set[3]) vor der Ausgabe. Dann dürfte dein Problem wahrscheinlich gelöst sein...

    Grüße Andres Freund

    1. Servus,

      ich weiss zwar nicht, woher am 3. Wett der Zeilenumbruch kommt, aber ok.
      Inzwischen habe ich das ganze etwas umgemodelt.

      sub count {
         my ($page,$ipnum)=@_ ;
         my $checknone = 0;
         my $date= &datum_zeit;
         my $lock = 1;
         my @output ;

      my @lines;
         my $i=0;
         #Daten laden
         open (DAT , "< ./data/stat.log") || die "Kann Datenfile (/data/stat.log) nicht zum Lesen öffnen" ;
         @lines = <DAT> ;
         close(DAT) ;

      #Count schreiben
         foreach $line (@lines)
            {
               $i = $i +1;
               my ($num, $pgname, $ipadress, $datum) = split(/&&/, $line) ;
               $datum=chomp($datum);
               if ($pgname eq $page)
                  {
                      $num++;
                      $checknone = 1;
                      $output[i]="$num&&$pgname&&$ipadress&&$datum&&" ;
                  }
                  else
                  {
                      $output[i]="$num&&$pgname&&$ipadress&&$datum&&" ;
                  }
            }
            if ($checknone == 0)
            {
           $i = $i +1;
           $output[i]="1&&$page&&$ipnum&&$date&&" ;
            }
         open (DAT , "> ./data/stat.log") || die "Kann Datenfile (/data/stat.log) nicht zum Schreiben öffnen" ;
         print DAT "@output";
         close(DAT) ;

      }

      sub datum_zeit {
      our $CONFIG;

      my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time+(3600*$CONFIG{'ZEITVERH'}));
      my $datum = sprintf "%02d.%02d.%04d : %02d:%02d" , $mday , $mon+=1 ,$year+=1900 , $hour , $min ;

      return($datum) ;

      }

      Klappen tut es immer noch nicht. Jetzt wird exakt immer nur ein Wert raus geschrieben, obwohl obige 1. $pgname eq $page Bedingung gar nicht sein kann.

      Gruss Matze

      1. Hallo

        $output[i]="$num&&$pgname&&$ipadress&&$datum&&" ;

        Wenn ich das anhand von $output richtig verstehe, benutzt du "&&"
        als Separator in einer textdateibasierten Datenbankzeile.
        Wenn aber hinter dem $datum noch ein Separator kommt, ist der
        Zeilenumbruch mit:

        $datum=chomp($datum);

        wohl nicht herauszufiltern, weil nicht am vermuteten Ort, sondern hinter dem
        abschließenden "&&", welches du ja nicht in eine Variable überführst:

        my ($num, $pgname, $ipadress, $datum) = split(/&&/, $line) ;

        Übrigens finde ich bei keiner deiner $output-Varianten eine Anfügung eines
        Zeilenumbruchs. Hier mal der Code für eine neue Zeile als Beispiel:

        $output[i]="1&&$page&&$ipnum&&$date&&" ;

        Vielleicht so:

        $output[i]="1&&$page&&$ipnum&&$date\n" ;

        Dann passt auch das chomp($datum); wieder, denk' ich mal.

        Tschö, Auge

        --
        Die Musik drückt aus, was nicht gesagt werden kann und worüber es unmöglich ist zu schweigen.
        (Victor Hugo)
        1. Servus,

          entschuldige diesmal ist der Zeilenumbruch irrelevant.
          Ich erzeige pro Eintrag in einem Aray eine neue Zeile.
          Sieht man unten.
          Dieses Array wird dann in das Dokument geschrieben.

          -> Leider kommt auch hier das Script über 2 Einträge nicht heraus.
          Obwohl ja beim ersten open die @list alle Einträge enthalten sollte.

          Gruss Matze

      2. sub count {
           my ($page,$ipnum)=@_ ;
           my $checknone = 0;
           my $date= &datum_zeit;
           my $lock = 1;
           my @output ;

        my @lines;
           my $i=0;
           #Daten laden
           open (DAT , "< ./data/stat.log") || die "Kann Datenfile (/data/stat.log) nicht zum Lesen öffnen" ;

        $! sagt dir dann auch warum.

        @lines = <DAT> ;
           close(DAT) ;

        Wenn du die Zeilenumbrüche nicht brauchst, dann mach das hier:

        chomp(@lines = <DAT> );

        #Count schreiben
           foreach $line (@lines)
              {
                 $i = $i +1;

        $i++;

        my ($num, $pgname, $ipadress, $datum) = split(/&&/, $line) ;
                 $datum=chomp($datum);
                 if ($pgname eq $page)

        Ist in $page wirklich ein String?

        {
                        $num++;
                        $checknone = 1;

        $checknone++;

        $output[i]="$num&&$pgname&&$ipadress&&$datum&&" ;

        Was ist i?
        Du meinst $i

        }
                    else
                    {
                        $output[i]="$num&&$pgname&&$ipadress&&$datum&&" ;
                    }

        $output[$i] hat kein \n, d.h. es wird später alles in eine Zeile geschrieben.

        }
              if ($checknone == 0)

        if (!$checknone)

        {
             $i = $i +1;

        $i++;

        $output[i]="1&&$page&&$ipnum&&$date&&" ;

        }
           open (DAT , "> ./data/stat.log") || die "Kann Datenfile (/data/stat.log) nicht zum Schreiben öffnen" ;
           print DAT "@output";

        Wenn du ein Array so ausgibst, werden die Elemente mit dem LIST_SEPARATOR Zeichen getrennt:

        Probier es aus:

        my @list = (1...10);
        $" = ";";

        print "@list";

        D.h. du hast in deiner Datei eine Zeile in der die Datensätz mit einem Leerzeichen (Defaultwert von $") getrennt sind.

        Struppi.

        1. Servus,

          au mann bi ich blöde..

          Wenn du die Zeilenumbrüche nicht brauchst, dann mach das hier:

          chomp(@lines = <DAT> );

          Die sollten in der 2. Version gar nicht mehr drinnen sein.

          Ist in $page wirklich ein String?

          Ja ganz sicher, vertrau mir.

          Was ist i?
          Du meinst $i

          Bin ich blöde. genau das wars.

          Gruss Matze

          1. Was ist i?
            Du meinst $i

            Bin ich blöde. genau das wars.

            Kann es sein das du ohne Warnings arbeitest?

            Das solltest du besser ändern, damit vermeidest du solche Fehler.

            Struppi.

      3. Hi,

        Inzwischen habe ich das ganze etwas umgemodelt.

        Hm, bei mir sieht es so aus, und funktioniert:

        #!/usr/bin/perl -w
        use strict;
        count("tes3t1",1231234212);
        count("tes3423",123132412312);
        count("tes32344512",12315522312);
        sub count {
             my ($page,$ipnum)=@_ ;
             my $checknone = 0;
             my $date= "2222";
             my $lock = 1;
             #Daten laden
             open (DAT , "< ./stat.log") || die "Kann Datenfile (/data/stat.log) nicht zum Lesen öffnen" ;
             my @lines = <DAT> ;
             close(DAT) ;
             #Count schreiben
             open (DAT , "> ./stat.log") || die "Kann Datenfile (/data/stat.log) nicht zum Schreiben öffnen" ;
             flock(DAT,2) if ($lock==1) ;
             foreach (@lines)
             {
           my @poll_set = split(/|/,$_);
           if ($poll_set[1] eq $page)
           {
                $poll_set[0]++;
                $checknone = 1;
           }
           chomp $poll_set[3];
           print DAT "$poll_set[0]|$poll_set[1]|$poll_set[2]|$poll_set[3]|\n";
             }
             close(DAT) ;

        if ($checknone == 0)
             {
           #
           open (DAT,">> ./stat.log") || die "Kann Datenfile (/data/stat.log) nicht zum Schreiben öffnen";
           flock(DAT,2) if ($lock==1) ;
           print DAT "1|$page|$ipnum|$date\n";
           close(DAT);
             }
        }

        Tut mir leid, ich hab gerade keine Lust auf wirkliches erklären, da du scheinbar allen Fragestellungen auszuweichst.

        Grüße, Andres Freund

        1. Servus,

          [pref:t=72658&m=418994]

          letze und aktuelle Version.
          Selbst wenn ich Dein Script nehme und entsprechend einbinde kommt nicht`s brauchbares dabei raus.
          Es klappt wirklich nicht.

          Mit der neuen Version habe ich nur noch das Problem, dass wenn eijn Eintrag vorhanden ist, alle anderen aus der Liste verschwinden.
          Das anfügen bzw. erhöhen des Wertes des zutreffenden Listeneintrages klappt.

          Warum das jedoch so ist erstehe ich keines wegs.

          Tut mir leid, ich hab gerade keine Lust auf wirkliches erklären, da du scheinbar allen Fragestellungen auszuweichst.

          Stimmt doch gar nicht. Du hast 1. nich gefragt. 2. Habe ich nebenher selbst noch den Fehler gesucht und dabei das Script geändert.
          Dass dabei manche alte Frage überflüssig wird erklärt sich von selbst.

          Gruss Matze

          1. Tut mir leid, ich hab gerade keine Lust auf wirkliches erklären, da du scheinbar allen Fragestellungen auszuweichst.

            Stimmt doch gar nicht. Du hast 1. nich gefragt. 2. Habe ich nebenher selbst noch den Fehler gesucht und dabei das Script geändert.
            Dass dabei manche alte Frage überflüssig wird erklärt sich von selbst.

            wenigstens den Hinwies mit den Warnungen solltest du aber trotzdem ernst nehmen.

            Struppi.

            1. Servus,

              wenigstens den Hinwies mit den Warnungen solltest du aber trotzdem ernst nehmen.

              Ich schau doch schon ins apache log.
              Weder die Acess noch die error log ergeben etwas aufschlussreiches.

              Gruss Matze

  2. Servus,

    also nochmals.
    Das erste Script, welches lediglich ein get bekommt auswertet.

    #!c:\perl58\bin\perl.exe

    use strict;
    use Config::IniFiles;
    use CGI::Carp qw(fatalsToBrowser);
    use CGI;

    #Ermittlung des Scriptnamens und des Verzeichnisses
    #und Wechsel in das aktuelle Verzeichnis (CGI)
    $0 =~ /^(.*)[/\].*/ && chdir ($1) ;

    require "./libs/statistic.cgi" ;

    Notwendige Informationen werden gelesen.

    Diese müssen immer als POST Parameter übergeben werden.

    my $template = "";
    my $query     = new CGI;
    my $page;
    my $cfg = new Config::IniFiles -file => "./conf/conf.ini";
    $page = $query->param('seite');

    Laden der Configuration aus der ini Datei.

    #Host
    my $cgi_host= $cfg->val( 'Server', 'DocumentRoot' ) ;

    #WWW-Pfad dieses Files (ohne Host)
    my $cgi_dir="$cgi_host/cgi-bin" ;

    #Backlink (zurück auf der Übersichtsseite)
    my $back_link="$cgi_host/index.html" ;

    Verzeichnis zu den Bildern.

    my $pic_dir="$cgi_host/images/";

    Verzeichnis zum template

    my $tmpl_dir="$cgi_host/tmpl/";

    open (DAT, "< ../$page.html") || die "Kann das Template -tmpl/vote.tmpl- nicht laden." ;
    undef $/ ;
    my $seite_txt=<DAT> ;
    close (DAT) ;

    count($page,127001);

    &print_mess($seite_txt);

    sub print_mess {

    my $mess_txt = shift;

    open (DAT, "< tmpl/sturm.tmpl") || die "Kann das Template -tmpl/vote.tmpl- nicht laden." ;
    undef $/ ;
    my $back=<DAT> ;
    close (DAT) ;

    $back =~ s/[MESSAGE]/$mess_txt/g ;
    $back =~ s/[PICDIR]/$pic_dir/g ;
    $back =~ s/[HOME]/$back_link/g ;
    $back =~ s/[GETPAGECGI]/$cgi_dir/getpage.cgi/g ;

    print "Content-type: text/html\n\n" ;
    print $back;

    }

    ####################

    Hier nun das 2 Script die lib -> Mein Problemfall

    ####################

    #!/usr/bin/perl
    use Time::Local 'timelocal_nocheck' ;
    use CGI::Carp qw(fatalsToBrowser) ;
    use strict;

    ############################################################################

    Counter

    ############################################################################

    sub count {
       my ($page,$ipnum)=@_ ;
       my $checknone = 0;
       my $date= "12345";
       my $lock = 1;
       my @output ;

    my @lines;
       my $i=0;
       #Daten laden
       open (DAT , "< ./data/stat.log") || die "Kann Datenfile (/data/stat.log) nicht zum Lesen öffnen" ;
       @lines = <DAT> ;
       close(DAT) ;

    #Count schreiben
       foreach my $line (@lines)
          {
             chomp $line ;
             my ($num, $pgname, $ipadress, $datum) = split(/&&/, $line) ;
             chomp $datum ;

    if ($pgname eq $page)
                {
                    $num++;
                    $checknone = 1;
                    $output[$i]="$num&&$pgname&&$ipadress&&$datum&&" ;
                }
                else
                {
                    $output[$i]="$line" ;
                }
                $i++;

    }
          if ($checknone == 0)
          {
          $i++;
          $output[$i]="1&&$page&&$ipnum&&$date&&" ;
          }
       open (DAT , "> ./data/stat.log") || die "Kann Datenfile (/data/stat.log) nicht zum Schreiben öffnen" ;
       print DAT "@output";
       close(DAT) ;

    }

    #sub datum_zeit {
    #our $CONFIG;

    #my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time+(3600*$CONFIG{'ZEITVERH'}));
    #my $datum = sprintf "%02d.%02d.%04d : %02d:%02d" , $mday , $mon+=1 ,$year+=1900 , $hour , $min ;

    #return($datum) ;

    #}

    #############################################################################

    ENDE

    #############################################################################

    1 ;

    Egal was ich versuche.... die stat.log ist innerhalb weniger aufrufe zerbröselt.
    Das erst Script funktioniert hingegen tadellos und liefert mir immer die gewünschte seite -> $page.

    Gruss Matze

    1. also nochmals.
      Das erste Script, welches lediglich ein get bekommt auswertet.

      #!c:\perl58\bin\perl.exe

      use strict;
      use Config::IniFiles;
      use CGI::Carp qw(fatalsToBrowser);
      use CGI;

      also ausser das die Warnungen fehlen.

      open (DAT , "< ./data/stat.log") || die "Kann Datenfile (/data/stat.log) nicht zum Lesen öffnen" ;
         @lines = <DAT> ;
         close(DAT) ;

      #Count schreiben
         foreach my $line (@lines)
            {
               chomp $line ;
               my ($num, $pgname, $ipadress, $datum) = split(/&&/, $line) ;
               chomp $datum ;

      if ($pgname eq $page)
                  {
                      $num++;
                      $checknone = 1;
                      $output[$i]="$num&&$pgname&&$ipadress&&$datum&&" ;
                  }
                  else
                  {
                      $output[$i]="$line" ;
                  }
                  $i++;

      }
            if ($checknone == 0)
            {
            $i++;
            $output[$i]="1&&$page&&$ipnum&&$date&&" ;
            }
         open (DAT , "> ./data/stat.log") || die "Kann Datenfile (/data/stat.log) nicht zum Schreiben öffnen" ;
         print DAT "@output";

      Du hast hier keine Trenner mehr zwischen deine Datensätzen.

      close(DAT) ;

      }

      würd ich hier, die Datei zum lesen + schreiben öffnen
      Dann flocken dazu musst du sie aber dann erst löschen (truncate) und den Filezeiger auf den Anfang setzten.

      Das ist sicherere als das.

      struppi.

      1. Servus,

        Du hast hier keine Trenner mehr zwischen deine Datensätzen.

        Ja stimmt das Script sieht inzwischen auch anderster aus.
        [pref:t=72769&m=419154]

        würd ich hier, die Datei zum lesen + schreiben öffnen
        Dann flocken dazu musst du sie aber dann erst löschen (truncate) und den Filezeiger auf den Anfang setzten.

        Das locken der Datei bau ich später wieder ein.

        Aktuell muss ich es erst mal zum laufen bekommen.
        Das dumme ist, dass es über einen Webzugriff angetriggert wird.

        Solange ich es auf der console direkt aufrufe klappt es nur übers Web da klappt es überhaubt nicht.
        Aber im neuen Thread ist es besser beschrieben und hat auch nicht`s mehr damit zu tun, warum der Zeilenumbruch nicht ausgegeben wird.

        Gruss Matze