Sample program from Programming Perl (Camel book) not running as expected

H

hiabhijeet

I am trying to execute the following sample program on WINDOWS but its not executing as expected. Its only reading the first line from the file and displaying it. Its not reading the rest of the lines -

open(GRADES, "grades") or die "Can't open grades: $!\n";
while(defined($line = <GRADES>)) {
print "[1] - $line\n";
($student, $grade) = split(" ", $line);
$grades{$student} .= $grade . " ";
print "[2] - $student\t$grade\n";
}

foreach $student (sort keys %grades) {
print "[3] - $student\n";
$scores = 0;
$total = 0;
@grades = split(" ", $grades{$student});
foreach $grade (@grades) {
$total += $grade;
$scores++;
}
$average = $total / $scores;
print "$student: $grades{$student}\tAverage: $average\n";
}

Please note - "grades" is a file that contains below data -

Noël 25
Ben 76
Clementine 49
Norm 66
Chris 92
Doug 42
Carol 25
Ben 12
Clementine 0
Norm 66
 
M

Michael Vilain

I am trying to execute the following sample program on WINDOWS but its not
executing as expected. Its only reading the first line from the file and
displaying it. Its not reading the rest of the lines -

open(GRADES, "grades") or die "Can't open grades: $!\n";
while(defined($line = <GRADES>)) {
print "[1] - $line\n";
($student, $grade) = split(" ", $line);
$grades{$student} .= $grade . " ";
print "[2] - $student\t$grade\n";
}

foreach $student (sort keys %grades) {
print "[3] - $student\n";
$scores = 0;
$total = 0;
@grades = split(" ", $grades{$student});
foreach $grade (@grades) {
$total += $grade;
$scores++;
}
$average = $total / $scores;
print "$student: $grades{$student}\tAverage: $average\n";
}

Please note - "grades" is a file that contains below data -

Noël 25
Ben 76
Clementine 49
Norm 66
Chris 92
Doug 42
Carol 25
Ben 12
Clementine 0
Norm 66

Check the line endings on the file. I don't know if the Windows Perl
implementation uses "\n" as a line ending as UNIX and MacOS versions of
Perl or "\r\n" for Windows standard. How do you know what is what?
That depends on the editor you're using, I think.
 
H

hiabhijeet

Thanks. Yes... would like to know what would make this program work on Windows. About the file format - I used UltraEdit to save this file in DOS mode.
 
H

hiabhijeet

Hey.. got this to work. Earlier I had copy pasted the file contents from the book pdf to notepad. Now reworte the data from scratch in a new file (using UltraEdit) and saved it as it is. Now program works fine!!
 
R

Rainer Weikusat

Michael Vilain said:
I am trying to execute the following sample program on WINDOWS but its not
executing as expected. Its only reading the first line from the file and
displaying it. Its not reading the rest of the lines -
[...]

Check the line endings on the file. I don't know if the Windows Perl
implementation uses "\n" as a line ending as UNIX and MacOS versions of
Perl or "\r\n" for Windows standard.

This is supposed to be transparent for files opened in text mode (the
default): A WinDOS/2-perl should translate \xd\xa to 'a logical \n' on
input and translate this 'logical \n' back to \xd\xa on output except
if binmode was used to disable this behaviour.

NB: I haven't tested this.
 
M

MeV

Michael Vilain said:
I am trying to execute the following sample program on WINDOWS but itsnot
executing as expected. Its only reading the first line from the file and
displaying it. Its not reading the rest of the lines -


[...]

Check the line endings on the file. I don't know if the Windows Perl
implementation uses "\n" as a line ending as UNIX and MacOS versions of
Perl or "\r\n" for Windows standard.

This is supposed to be transparent for files opened in text mode (the
default): A WinDOS/2-perl should translate \xd\xa to 'a logical \n' on
input and translate this 'logical \n' back to \xd\xa on output except
if binmode was used to disable this behaviour.



NB: I haven't tested this.

It definitely isn't transparent on MacOS X. If you open a Windows-formatted file in MacOS X perl, you get the exact behavior he described. That's what twigged me to the problem. If you change the file to UNIX line-endings,the problem goes away and perl works as expected.

Don't know what editors there are on Windows that support setting or changing the line-endings. vi on Unix will tell you if a Windows file has ^M line endings. BBEdit and Textwrangler on MacOS supports this trivially.
 
R

Rainer Weikusat

MeV said:
Michael Vilain said:
(e-mail address removed) wrote:

I am trying to execute the following sample program on WINDOWS but its not
executing as expected. Its only reading the first line from the file and
displaying it. Its not reading the rest of the lines -



[...]

Check the line endings on the file. I don't know if the Windows Perl
implementation uses "\n" as a line ending as UNIX and MacOS versions of
Perl or "\r\n" for Windows standard.

This is supposed to be transparent for files opened in text mode (the
default): A WinDOS/2-perl should translate \xd\xa to 'a logical \n' on
input and translate this 'logical \n' back to \xd\xa on output except
if binmode was used to disable this behaviour.



NB: I haven't tested this.

It definitely isn't transparent on MacOS X. If you open a
Windows-formatted file in MacOS X perl, you get the exact behavior
he described. That's what twigged me to the problem. If you change
the file to UNIX line-endings, the problem goes away and perl works
as expected.

Well, a MAC OS X perl is supposed to handle MAC OS X text files
'transparently' (suprising, ain't int?) in the same way a Windows perl
is supposed to handle Windows text files transparently ...
 
M

Michael Vilain

Rainer Weikusat said:
MeV said:
(e-mail address removed) wrote:

I am trying to execute the following sample program on WINDOWS but its
not
executing as expected. Its only reading the first line from the file
and
displaying it. Its not reading the rest of the lines -




[...]

Check the line endings on the file. I don't know if the Windows Perl
implementation uses "\n" as a line ending as UNIX and MacOS versions of
Perl or "\r\n" for Windows standard.

This is supposed to be transparent for files opened in text mode (the
default): A WinDOS/2-perl should translate \xd\xa to 'a logical \n' on
input and translate this 'logical \n' back to \xd\xa on output except
if binmode was used to disable this behaviour.



NB: I haven't tested this.

It definitely isn't transparent on MacOS X. If you open a
Windows-formatted file in MacOS X perl, you get the exact behavior
he described. That's what twigged me to the problem. If you change
the file to UNIX line-endings, the problem goes away and perl works
as expected.

Well, a MAC OS X perl is supposed to handle MAC OS X text files
'transparently' (suprising, ain't int?) in the same way a Windows perl
is supposed to handle Windows text files transparently ...

There's a big difference between 'supposed to' and actuality. Kinda
like the architect's plans and the builder's 'built-as' drawings.

Googling for 'perl windows line endings' gives lots of solutions to this
problem. But if the OP didn't know there was a problem to begin with,
then they'd be mystified by why Windows Perl doesn't work the same as
documented in the Camel book.

I had to write a perl script to convert and import a CSV file into MySQL
but I never new where that script would be coming from. So I had to
build the line-ending detection into my code. I think it was quite easy
once you know that's an issue.
 
R

Rainer Weikusat

Michael Vilain said:
[...]
I am trying to execute the following sample program on WINDOWS but its
not
executing as expected. Its only reading the first line from the file
and
displaying it. Its not reading the rest of the lines -




[...]

Check the line endings on the file. I don't know if the Windows Perl
implementation uses "\n" as a line ending as UNIX and MacOS versions of
Perl or "\r\n" for Windows standard.

This is supposed to be transparent for files opened in text mode (the
default): A WinDOS/2-perl should translate \xd\xa to 'a logical \n' on
input and translate this 'logical \n' back to \xd\xa on output except
if binmode was used to disable this behaviour.



NB: I haven't tested this.

It definitely isn't transparent on MacOS X. If you open a
Windows-formatted file in MacOS X perl, you get the exact behavior
he described. That's what twigged me to the problem. If you change
the file to UNIX line-endings, the problem goes away and perl works
as expected.

Well, a MAC OS X perl is supposed to handle MAC OS X text files
'transparently' (suprising, ain't int?) in the same way a Windows perl
is supposed to handle Windows text files transparently ...

There's a big difference between 'supposed to' and actuality. Kinda
like the architect's plans and the builder's 'built-as' drawings.

In this case, this has been documented functionality since
I-don't-know-when (presumably, since a Perl port of Windows existed)
and consequently, the chances that a _Windows_ perl can't handle
_Windows_ text files despite the documentation says it can are IMO
very slim. OTOH, a _UNIX(*)_ perl won't be able to handle 'Windows text
files' in 'text mode' because it expects _UNIX(*)_ text files ...
Googling for 'perl windows line endings' gives lots of solutions to this
problem.

.... which happens to be consistent with your observation of a certain
(Free)BSD bastard and all of these "someone wrote this with notepad
and while it works on my laptop, it doesn't work on the webserver !!1"
tips.
 
S

Stuart Golodetz

Michael Vilain said:
(e-mail address removed) wrote:

I am trying to execute the following sample program on WINDOWS
but its not executing as expected. Its only reading the first
line from the file and displaying it. Its not reading the rest
of the lines -



[...]

Check the line endings on the file. I don't know if the Windows
Perl implementation uses "\n" as a line ending as UNIX and MacOS
versions of Perl or "\r\n" for Windows standard.

This is supposed to be transparent for files opened in text mode
(the default): A WinDOS/2-perl should translate \xd\xa to 'a
logical \n' on input and translate this 'logical \n' back to \xd\xa
on output except if binmode was used to disable this behaviour.



NB: I haven't tested this.

It definitely isn't transparent on MacOS X. If you open a
Windows-formatted file in MacOS X perl, you get the exact behavior he
described. That's what twigged me to the problem. If you change the
file to UNIX line-endings, the problem goes away and perl works as
expected.

Don't know what editors there are on Windows that support setting or
changing the line-endings. vi on Unix will tell you if a Windows
file has ^M line endings. BBEdit and Textwrangler on MacOS supports
this trivially.

Notepad++ will let you change line endings on Windows, for what it's worth.

- S
 
A

Andrew

I simply strip the carriage returns ("\t") whenever I get files of this type.

You can write a Perl script to batch-process your files, to simply strip the "\r", or you can use the command-line approach:

perl -pi.bak -e 's/\r//g' *.pl
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,733
Messages
2,569,439
Members
44,829
Latest member
PIXThurman

Latest Threads

Top