Difficulty removing element from array

R

Robert TV

Hi ... I'm loosing much hair over this array element removal problem i'm
having. I will describe my setup. I have a web form with a single text box
named "recipient" ... on submit, the data is passed to my delete.pl script.
In the same folder, there is a text file called "addresses.txt" This file
contains the following data:

Gerald Genry|[email protected]
Gerry Smith|[email protected]
Robert TV|[email protected]
Terry Valcourt|[email protected]
Dan Perterson|[email protected]
James Smiley|[email protected]

These are names and email addresses separated by a "|" symbol. Here is the
delete script I have so for that is not functional:

#############

#!/usr/bin/perl

use Fcntl qw:)DEFAULT :flock);
use CGI::Carp qw(fatalsToBrowser);

read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$form{$name} = $value;
}

open (ADDRESSES, "<addresses.txt") or die "Can't open file: $!";
@entrys=<ADDRESSES>;
close(ADDRESSES);

foreach $entry (@entrys) {
$count++;
if ($entry eq $form{'recipient'}) {
$count--;
splice(@entrys, $count, 1);
}
}

print @entrys;
exit;

#############

If I type "Terry Valcourt|[email protected]" in the web form and submit,
nothing happens. When @entrys prints, it still contains all entires read
from the text file. It's the same for any name and email address grouping
entered. To match the form input to the array element, I used the "eq"
operator. It is my belief that there is no successful matching because there
is a "\n" at the end of each "$entry". So I thought I might add a "chomp
($entry);" command to the equation that would remove the "\n"s from the end
of each $entry. Below is code with the chomp:

#############

#!/usr/bin/perl

use Fcntl qw:)DEFAULT :flock);
use CGI::Carp qw(fatalsToBrowser);

read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$form{$name} = $value;
}

open (ADDRESSES, "<addresses.txt") or die "Can't open file: $!";
@entrys=<ADDRESSES>;
close(ADDRESSES);

foreach $entry (@entrys) {
chomp ($entry);
$count++;
if ($entry eq $form{'recipient'}) {
$count--;
splice(@entrys, $count, 1);
}
}

print @entrys;
exit;

#############

This is where things get REALLY messed up. I go back to the web form and
type "Terry Valcourt|[email protected]" This time when @entrys prints, all
lines of data have been removed except "Dan Perterson|[email protected]" I've
spent hours trying to understand what is going on ... please help me see the
light!

P.S. I know most of you may look at my coding methods and laugh, bear in
mind i'm very new and still learning :)

Robert
 
C

Chief Squawtendrawpet

Robert said:
foreach $entry (@entrys) {
$count++;
if ($entry eq $form{'recipient'}) {
$count--;
splice(@entrys, $count, 1);
}
}

You're modifying an array while iterating over it, which seems like a bad
idea to me. If the entries are unique you could store them in a hash
instead of an array, making the deletion process very easy.
# Read entries [not tested]
while (<ADDRESSES>){
chomp; # Don't you need to remove the newlines from your entries?
$entrys{$_} = 1;
}
# Delete one
delete $entrys{$form{recipient}};

If the entries must be in an array, you could use grep() to delete those
matching $form{recipient}.
# Not tested
@entrys = grep $_ ne $form{recipient}, @entrys;

Chief S.
 
D

David Efflandt

Hi ... I'm loosing much hair over this array element removal problem i'm
having. I will describe my setup. I have a web form with a single text box
named "recipient" ... on submit, the data is passed to my delete.pl script.
In the same folder, there is a text file called "addresses.txt" This file
contains the following data:

Gerald Genry|[email protected]
Gerry Smith|[email protected]
Robert TV|[email protected]
Terry Valcourt|[email protected]
Dan Perterson|[email protected]
James Smiley|[email protected]

These are names and email addresses separated by a "|" symbol. Here is the
delete script I have so for that is not functional:

#############

#!/usr/bin/perl

use Fcntl qw:)DEFAULT :flock);
use CGI::Carp qw(fatalsToBrowser);

read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$form{$name} = $value;
}

open (ADDRESSES, "<addresses.txt") or die "Can't open file: $!";

If you are trying to remove a recipient from the stored list, try this
here instead (filter as you read them):

while (<ADDRESSES>) {
chomp;
push @entrys,$_ if $_ ne $form{'recipient'};
}
close ADDRESSES;
# add code to print them back to addresses.txt
print "Content-type: text/plain\n\n";
foreach (@entrys) { print "$_\n"; }
 
E

Eric J. Roode

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi ... I'm loosing much hair over this array element removal problem
i'm having. I will describe my setup. I have a web form with a single
text box named "recipient" ... on submit, the data is passed to my
delete.pl script. In the same folder, there is a text file called
"addresses.txt" This file contains the following data:

Gerald Genry|[email protected]
Gerry Smith|[email protected]
Robert TV|[email protected]
Terry Valcourt|[email protected]
Dan Perterson|[email protected]
James Smiley|[email protected]

These are names and email addresses separated by a "|" symbol. Here is
the delete script I have so for that is not functional:

#############

#!/usr/bin/perl

use Fcntl qw:)DEFAULT :flock);
use CGI::Carp qw(fatalsToBrowser);

read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$form{$name} = $value;
}

open (ADDRESSES, "<addresses.txt") or die "Can't open file: $!";
@entrys=<ADDRESSES>;
close(ADDRESSES);

foreach $entry (@entrys) {
$count++;
if ($entry eq $form{'recipient'}) {
$count--;
splice(@entrys, $count, 1);
}
}

print @entrys;
exit;

#############

If I type "Terry Valcourt|[email protected]" in the web form and submit,
nothing happens. When @entrys prints, it still contains all entires
read from the text file. It's the same for any name and email address
grouping entered. To match the form input to the array element, I used
the "eq" operator. It is my belief that there is no successful
matching because there is a "\n" at the end of each "$entry".

It is my belief that there is no successful matching because you're
trying to match the recipient to the whole line of name and | and email
address and newline. But that's only a guess, because you don't tell us
what the "recipient" field contains.

I would strongly recommend that you reorganize your program. You have
boilerplate code that parses out the CGI parameters. I'll bet you have
that same code in every one of your CGI programs. Why not move it to a
subroutine, so you don't have to copy/paste so much code everywhere?
Also, if you should need to change the code, you'll only need to change
it once in the subroutine module, rather than in every single program
file. (There are at least three bugs in the code that you posted).

Better yet, use the CGI.pm module. Why code by hand that which has been
done excellently already?

Also, I would encourage you to move your database handling code to a
module. You have a simple flat-file database model. Why not write
routines to add, update, delete, and look up records, and then just
invoke those routines everywhere you use the database, instead of writing
and debugging code to do those functions everywhere?

- --
Eric
$_ = reverse sort $ /. r , qw p ekca lre uJ reh
ts p , map $ _. $ " , qw e p h tona e and print

-----BEGIN PGP SIGNATURE-----
Version: PGPfreeware 7.0.3 for non-commercial use <http://www.pgp.com>

iQA/AwUBP223oWPeouIeTNHoEQJe7gCbBNy05RZ8J68eNxedjWSCYD4UhakAn0jI
H9lR+mcMVWcqdF3ymaNHIuMQ
=j0++
-----END PGP SIGNATURE-----
 

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

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,190
Members
46,736
Latest member
zacharyharris

Latest Threads

Top