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

This is a large and comprehensive site which seems to be mainly for the hard-core perl programmers so I hope you don't mind a quick question from a beginner? My problem is an @ symbol which appears at the end of my lines of text. The lines of text are read from a file and shoved through a 'format', where they are written back into another file. The lines of text which generate the mysterious '@' are feed into the 'format' where they are supposed to be written in a multi-line, as-much-as-you-can-give style, which is done by the @* line of code. Well, I hope I haven't confused you all too much. Here is some of my code. I hope you can pick up the problem from it:
# This is my format format FORMATTED = <font face="Arial"> @<<<<<<<<< </font> $date @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< $subject @* $article </font><hr size="1" noshade></p> . # This is where the text is pulled from a file and written into anothe +r using the format. open(FORMATTED, "> $newspage") || sendError("can't write to $newspage" +); open(DATAFILE, $articalsdat) || sendError("cant open articles file"); while (<DATAFILE>) { chomp; # remove newline ($date,$subject,$article) = (split(/-!news-/)); $date = "00/00/0000" if !defined($date); $subject = "no subject" if !defined($subject); $article = "no article" if !defined($article); write(FORMATTED); } close (DATAFILE);
When the new file ($articalsdat) is viewed, there is an @ symbol after every line of $article? why? Will the kind monks help?

Replies are listed 'Best First'.
Re: Strange @ appearance
by kschwab (Vicar) on Jul 29, 2001 at 05:26 UTC
    There's a small problem with the format. The line@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< $subject should be 2 lines...
    @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< $subject
    The only reason I can see for having '@' chars in the output is that perhaps you have '@' chars in the input. Add in a print STDOUT "[$date] [$subject] [$article]\n" line to find out what's in the variables. Maybe your split() is getting data you hadn't intended.

    Also, it's not hurting anything, but the extra parens around split() aren't needed.

    Update: Null characters sometimes look like '^@' in an editor. Perhaps the input file contains nulls ? Try doing a hex dump ( od -hc filename ) and see.

      Thanks 4 responding. Yes, I notice I put that $subject on the wrong line - it isnt in my actual code, just a typo. As for having '@' chars in the input, I don't know. The input is actually POSTed from a web page. I have decoded it like so:
      # Get POSTED info and stick it in $post_info. read (STDIN, $post_info, $ENV {'CONTENT_LENGTH'} ); # split off fields and put them in @InfoArray @InfoArray = split(/&/, $post_info); # Remove variable= part and translate data into real chars for ($n = 0; @InfoArray[$n]; $n++) { chomp; # remove newline ($dummy, $temp) = split (/=/, @InfoArray[$n]); $temp =~ tr/+/ /; $temp =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; @InfoArray [$n] = $temp; }
      Does anyone see something dodgy with that little lot? Also, yes, it may be a null character, but I have chomped and choped the last line of text, and even done a 'get rid of crap' command  $article =~ s/\ 0//g;, all to no avail. Sheesh, It's gonna take me a while to get used to PERL. It's very powerful and, if you know it, quick, but it's so untidy! Im a Java man you see...
        Yikes, don't try and implement CGI.pm yourself. See here for more info.

        Your loop is a little "dodgy", using array slices and such. Also, the chomp() is chomping $_, which means nothing in the context you gave it, since $_ is being set to the array index.

        If you end up not using CGI.pm (ack), rewrite the loop so that chomp actually does something.

        # iterate over the split # placing each element in $_ along the way my @InfoArray; for (split(/&/, $post_info)) { chomp; # remove newline ($dummy, $temp) = split (/=/, $_); $temp =~ tr/+/ /; # ack, urldecoding in a regex ? $temp =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; push(@InfoArray,$temp); }
        But do please try Cgi.pm...it's well equipped to pull out the form values, do the (un)encoding of urls, etc.
Re: Strange @ appearance
by bikeNomad (Priest) on Jul 29, 2001 at 19:39 UTC
    It seems like you're uncomfortably mixing two different idioms here.

    Perl's formats are designed to produce a simple formatted output on character devices (fixed-width, usually). These are used when the output device has no formatting capability of its own.

    But you're mixing HTML with it. Unless you're using preformatted text of some sort (like using <PRE>) and trying to make it look right using spaces, the spaces that are generated by the Perl formatted output will mostly be ignored.

    Wouldn't it be easier and cleaner (not to mention probably causing less network overhead) if you used HTML's own formatting capabilities to display this stuff as you want? Depending on your environment (intranet/Internet) you may consider using style sheets, which give quite a bit of flexibility for formatting.