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

i've encountered a pretty strange problem today dealing with an input/out file that uses a strange line ending format. the file is a configuration file for mcafee's netshield for netware, and instead of the normal DOS CR/LF (\x0D\x0A) line endings, it uses LF/CR (\x0A\x0D). ok, no problem, i'll just set up my input and output record seps and i'll be all set.

not quite.

take a look at this script:

$testvar1 = "\x0A\x0D"; $testvar2 = "\x0A\x0D"; $testvar3 = "\x0A"; $testvar4 = "\x0D"; $testvar5 = "foo\x0Abar"; print("testvar1 = \"$testvar1\"\n"); print("testvar2 = \"$testvar2\"\n"); print("testvar3 = \"$testvar3\"\n"); print("testvar4 = \"$testvar4\"\n"); print("testvar5 = \"$testvar5\"\n");

dumping this out to a file and examing the resulting text in a hex editor, i get the following:

testvar1 = "\x0D\x0A\x0D"
testvar2 = "\x0D\x0A\x0D"
testvar3 = "\x0D\x0A"
testvar4 = "\x0D"
testvar5 = "foo\x0D\x0Abar"

the values inside the quotes have been expanded back in hex notation by myself, and the real cr/lf on the end of each line ommitted. what looks to be happening is that any time perl win32 sees a LF in a string, it automagically prepends a CR. needless to say, this behavior is fantasticly annoying and i'd really like to disable it somehow. any thoughts from the bretheren?

luma::s-video

Replies are listed 'Best First'.
Re: ActivePerl 5.6.1 Win32 munging CR/LFs
by aquacade (Scribe) on Jul 25, 2001 at 01:06 UTC

    Perl is not C (I'm still learning this myself)! The string tokens of \n or \r [are not | do not seem to be] C style CHAR-type data per se! Please refer to Camel book PACK and UNPACK functions for do hex-based string manipulation (pg 757 3rd edition) for yet another way to handle the problem (if you like hex strings).

    Example:
    use strict; my $cr=pack("H2",'0d'); my $lf=pack("H2",'0a'); my $lfcr=$lf.$cr; my $ans=unpack("H4",$lfcr); print '$lfcr=x',"$ans\n";

    This will give your your linefeed/carrage return order, BUT depending how you're reading/manipulating your data (for example with <> and chop|chomp) you may need to clean the dangling single $lf's out yourself!

    Update:

    Thank you Tye, I stand humbly corrected (and learned something I didn't know) about what binmode does!

      No, no, no! Perl is nearly exactly like C in this regard. "\n" is always a single character. When it gets written to a non-binmode file under Win32, it gets turned into "\r\n". When it gets written to a (defaultly configured) device under Unix, it also gets turned into "\r\n" (but people don't worry much about that because you can't read the results back in).

              - tye (but my friends call me "Tye")
Re: ActivePerl 5.6.1 Win32 munging CR/LFs
by wine (Scribe) on Jul 24, 2001 at 22:41 UTC

    I guess this is a bug. Executing your code on Linux results in the expected output.

    I would just leave the \n out and use $\ if you want to force a line-ending in a print statement.

    BTW: This strange line-ending (LF/CR) is used on apple computers.

    Update I going to get some coffee ;)

      found it!

      binmode()

      i might add that mac's actually use a bare CR, not LF/CR.

      luma::s-video

Re: ActivePerl 5.6.1 Win32 munging CR/LFs
by aquacade (Scribe) on Jul 25, 2001 at 05:07 UTC

    The example above (which I copied and ran) is not reading or writing to a file except STDOUT. Can binmode effect STDIN/STDOUT/STDERR?

    The scalar assignments exhibit this behavior (assignments mind you) as shown (asked) in the original question above. Can anyone tell me why this is?

    My code example above was given as a way to store \x0a\x0d for use by the reader program since flipping it any other way with double quote interpolation (without PACK) elludes me. Is there another way to store hex 0a0d without using pack?

      Can binmode effect STDIN/STDOUT/STDERR?
      Yup, see for example this.

      -- Hofmator