engtech has asked for the wisdom of the Perl Monks concerning the following question:

I am still a beginner and am writing a very simple guestbook that writes the data to a file. My problem is that if the user should press the enter button while in the textarea to get a new line instead of waiting for the wordwrap then that also gets recorded to the file as a new line. When I read the file for output, anything on the new line(s) is missed because it is not a valid line containing an id number. How could I prevent this?
sub CheckForMsgs { my $strMsg = ''; my @MsgArray = (); my $MsgDate = 0; my $Message = ''; my $GuestName = ''; my $id = 0; my $colorflag = 0; my $bgcolor = "#FFFFCC"; # open the file for read open(DAT,"Guestbook.cgi") || die("Cannot Open File:$!"); @MsgArray = <DAT>; close(DAT); foreach $id (@MsgArray) { chomp ($id); ($id,$MsgDate,$GuestName,$Message)=split (/\|/,$id); # alternate table row background color to contrast entries. if ($id%2 eq 1){ $bgcolor = "#FFFFCC"; $strMsg .= "\ <tr bgcolor=\"$bgcolor\"><td> $MsgDate < +/td><td align=center> $GuestName </td><td> $Message </td></tr> \n"; } else { $bgcolor = "#DFDF00"; $strMsg .= "\ <tr bgcolor=\"$bgcolor\"><td> $MsgDate < +/td><td align=center> $GuestName </td><td> $Message </td></tr> \n"; } } return $strMsg; }; ####End of Sub sub WriteNewMsg { my @MsgArray = (); my $id = 0; my $NewMsg = ''; my $GuestName = ''; my $now_string = strftime "%a %b%e %H:%M %Y", localtime; my $NewID = 1; &ReadParse(*input); # open the file for read open(DAT,"Guestbook.cgi") || die("Cannot Open File:$!"); @MsgArray = <DAT>; close(DAT); open(DAT,">>Guestbook.cgi") || die("Cannot Open File:$!"); foreach $id (@MsgArray) { chomp ($id); ($id,$MsgDate,$GuestName,$NewMsg)=split (/\|/,$id); ++$NewID; } # add Event to file print DAT "$NewID|$now_string|$input{'txtGuestName'}|$input{'txtMs +g'}\n"; close(DAT); }; ###End of Sub

Replies are listed 'Best First'.
Re: Simple guestbook problem.
by Happy-the-monk (Canon) on Jul 01, 2004 at 21:08 UTC

    You should process the input from that textarea, replacing newlines with maybe <br> tags.

    Cheers, Sören

Re: Simple guestbook problem.
by muba (Priest) on Jul 01, 2004 at 21:05 UTC
    Three options.
    One: don't use text area's. Just use normal text boxes (no new lines allowed) instead.
    But this is not too pretty, so:

    Two: instead of thinging about $Message of a string of one line, read until you find a special line, for example: "#!#!END OF MESSAGE !#!#\n";
    Everything, from the end of the message headers (author and such) of the message until that line should be considered the actual message.

    Three: see the reply below. That one is even better!

    Update: "added" an option :) © Happy-the-monk

    "2b"||!"2b";$$_="the question"
Re: Simple guestbook problem.
by beable (Friar) on Jul 01, 2004 at 23:11 UTC
    Something like this might work:
    # replace newlines in message with brs my $msg = $input{'txtMsg'}; $msg =~ s|\r||g; $msg =~ s|\n|<br/>|g; # add Event to file print DAT "$NewID|$now_string|$input{'txtGuestName'}|$msg\n";
Re: Simple guestbook problem.
by nightwatch (Scribe) on Jul 01, 2004 at 23:21 UTC

    Use a sentinel value, such as '*' on a line by itself, to mark the end of each entry. Read perlvar for information on the $/ variable, which you can change from its default "\n" or "\r\n" to your sentinel value (say, "$/*$/"). If you do that, your use of the diamond operator in list context will still read all the results and place them into an array.

    Be sure to sanitize your content in some way to prevent cross-site-scripting vulnerabilities and abuse of your sentinel value; a combination of simple regexes and the CPAN HTML::Sanitizer should do the trick.

    Finally, it's somewhat misleading to name your file "Guestbook.cgi." The extension .cgi represents an executable CGI script, not a text file. Consider .txt or .dat.