Unexpected chomp() results


E

Exide Arabellan

Greetings,

In the following code im trying to remove the ending newline (\n) from
$login_attempt and print it to $client.

---
1. #! /usr/bin/perl -w
2.
3. use strict;
4. use IO::Socket;
5.
#.. declaring variables and printing local info to <STDOUT> ..
28.
29. while (my $client = $server->accept()) {
30. $client->autoflush(1);
31. print $client "username: ";
32. while (<$client>) {
33. my $login_attempt;
34. $login_attempt = $_;
35. chomp($login_attempt);
36. print $client "Account '".$login_attempt."' does not exist. Please
try again.";
37. }
38. }
---

Returns:
' does not exist. Please try again.

Instead of:
Account 'foo' does not exist. Please try again.

I tried writing a simple test script using lines 33-36 (replacing $_
with <STDIN> on line 35) and it worked as i had expected. Any thoughts?

Ryan Zander
www.arabellan.com
 
Ad

Advertisements

J

J Krugman

In said:
Greetings,
In the following code im trying to remove the ending newline (\n) from
$login_attempt and print it to $client.
---
1. #! /usr/bin/perl -w
2.
3. use strict;
4. use IO::Socket;
5.
#.. declaring variables and printing local info to <STDOUT> ..
28.
29. while (my $client = $server->accept()) {
30. $client->autoflush(1);
31. print $client "username: ";
32. while (<$client>) {
33. my $login_attempt;
34. $login_attempt = $_;
35. chomp($login_attempt);
36. print $client "Account '".$login_attempt."' does not exist. Please
try again.";
37. }
38. }
---
Returns:
' does not exist. Please try again.
Instead of:
Account 'foo' does not exist. Please try again.


What do you get if you print $login_attempt before chomping it?

jill
 
G

Glenn Jackman

Exide Arabellan said:
4. use IO::Socket; [...]
29. while (my $client = $server->accept()) {
30. $client->autoflush(1);
31. print $client "username: ";
32. while (<$client>) {
33. my $login_attempt;
34. $login_attempt = $_;
35. chomp($login_attempt); [...]
Returns:
' does not exist. Please try again.
Instead of:
Account 'foo' does not exist. Please try again.


Aren't lines sent over a TCP socket terminated with "\r\n"?
If so, chomp is insufficient with the default $/, because it won't
remove the \r.

Set $/="\r\n" before line 29, or wrap that while loop with:
{
local $/ = "\r\n";
while (my $client = $server->accept()) { ... }
}
 
E

Exide Arabellan

Glenn said:
Aren't lines sent over a TCP socket terminated with "\r\n"?
If so, chomp is insufficient with the default $/, because it won't
remove the \r.

Set $/="\r\n" before line 29, or wrap that while loop with:
{
local $/ = "\r\n";
while (my $client = $server->accept()) { ... }
}

That was it :) I figured it was something to do with 'print'ing over a
socket. Thanks for the help.
 
Ad

Advertisements

U

Uri Guttman

EA> 32. while (<$client>) {
EA> 33. my $login_attempt;
EA> 34. $login_attempt = $_;

why all the copying and declaring?
while (my $login_attempt = <$client>) {

EA> 35. chomp($login_attempt);
EA> 36. print $client "Account '".$login_attempt."' does not
EA> exist. Please try again.";
EA> 37. }
EA> 38. }
EA> ---

EA> Returns:
EA> ' does not exist. Please try again.

EA> Instead of:
EA> Account 'foo' does not exist. Please try again.

you are probably reading a line with cr/lf ending from the server and
chomping away only the lf (\n). chomp uses $/ which had a platform
default. the symptom you see is the cr causing the line to overwrite
part of itself when printing on a screen. the data was output, but you
just don't see it all.

several solutions. the simplest is to do a real strip with a regex:

$login_attempt =~ s/[\r\n]+\z// ;

uri
 
Ad

Advertisements


Top