Re: string retrieval issue
- From: Ben Morrow <benmorrow@xxxxxxxxxxxxx>
- Date: Thu, 14 Dec 2006 20:55:12 +0000
Quoth mbliven1@xxxxxxxxx:
Paul Lalli wrote:
mbliven1@xxxxxxxxx wrote:
That's where I'm stuck. If the flat file looks like this:
Chicago Bears|NFC North
Detroit Lions|NFC North
then everything is great. However, if my file looks like this:
Chicago Bears|NFC North
Chicago Bulls|East Conference
then the script fails. In other words, if both lines begin with the
exact same string to the first space, then it will fail. It fails by
not writing the third element (Chicago Bulls) back to the array).
Ideas?
... You obviously did something wrong. How, precisely, are you
expecting anyone to tell you what you did wrong without seeing the code
you wrote?
Have you read the Posting Guidelines for this group? They're posted
here twice a week. I suggest you read them before replying.
My bad about the post. I have now read the guidelines.
....but seem to be unwilling to follow them.
Here is the code:
Where is
use strict;
use warnings;
?
open (FILE, "+<test.txt") || die ("test.txt wont open");
Use two-arg open.
Use lexical filehandles.
Say why the open failed.
The first rule of programming is: never type anything twice. Put the
filename in a variable.
my $database = 'test.txt';
open(my $FILE, '+<', $database) || die("'$database' won't open: $!");
If you use or instead of || those parens are optional:
open my $FILE, '+<', $database
or die "can't open '$database': $!";
but the code's OK like that if you find it easier to understand.
flock FILE, 2;
Don't *ever* use numeric constants for flock, seek, &c. Ask Perl to get
them right for you.
Check that you got the lock.
use Fcntl qw/:flock/; # this goes at the top
flock $FILE, LOCK_EX
or die "can't lock '$database': $!";
@lines = <FILE>;
You need to declare variables under 'use strict'.
my @lines = <$FILE>;
$j=0;
$k=0;
These would need declaring as well, except you very rarely need loop
counters in Perl. Perl knows how long your arrays are.
You do, however, need
my @splitdata;
foreach $element (@lines) {^^ my
($element1, $element2) = split(/\|/, $element);
Variables with similar names are a red flag. They mean you should be
using data structures: in this case, an array.
my @elements = split(/\|/, $element);
@splitdata[$j] = $element1;
Don't use @ for accessing single array elements. It appears to work, but
it doesn't mean quite what you think it does. See perldoc -q @array.
$splitdata[$j] = $element1;
@splitdata[$k] = $element2;
This is pointless. $j and $k will always be equal, so you set the same
element twice. Every other element will be blank. I presume you meant to
set successive elements?
Use Perl's array operators, and then you don't need the temporaries
either:
push @splitdata, split /\|/, $element;
$j = $j + 2;
It's generally clearer to use the assignment operators where you can:
$j += 2;
, except, of course, that you don't need this at all.
$k=$k + 2;
}
foreach $p (param()) {
What is param? You didn't include it in your script. I'm going to guess
you meant to put
use CGI qw/:standard/;
at the top: when the posting guidelines say 'a short, complete script'
they mean you need to post the *whole* of your script. You also need to
provide example input: in this case, a query string.
Note that the order of parameters is not guaranteed to be the same as
the order of fields in the form. You should give your paramaters names
and access them by name.
$formvalue = param($p);
@formvalue[$i] = $formvalue;
if ($formvalue eq "") {
@final[$i] = @splitdata[$i];
}
else {
@final[$i] = $formvalue;
}
This can be written more simply as
$final[$i] = $formvalue || $splitdata[$i];
$i++;
}
I don't really understand what you are trying to achieve here. A
somewhat cleaner solution might be
my @params = params;
my %final;
$final{$_} = shift @splitdata for @params;
$final{$_} = param($_) for grep param($_), @params;
but I really think that a better answer would be to put the form field
names into your database. Do you have to use that file format? If you
could change to something like GDBM, then you could reduce the whole
script down to
use warnings;
use strict;
use GDBM_File;
use CGI qw/:standard/;
tie my %data, GDBM_File => './data', GDBM_WRCREAT;
$data{$_} = param($_) for grep param($_), params;
as GDBM handles locking for you. This will consider a parameter value of
'0' to be equivalent to '', so you may prefer
$data{$_} = param($_) for grep { length param($_) }, params;
It also assumes that your fields all have unique names; again, this may
not be the case, but you didn't provide us with any input data.
$x=0;
$y=0;
$z=0;
foreach (@final) {
$firstpart = @final[$x];
$secondpart = @final[$y];
Again, $x and $y are the same, so you're getting the same element twice.
Also, the loop loops once for every element in @final, but you're adding
2 to $x each time, so before long you'll be off the end of the array.
$writevalue = "$firstvalue|$secondpart";
What is $firstvalue? Is this your real script, or is that the bug you
were having trouble with? I can't see how it would produce the effect
you describe, though, unless this is not your whole script.
@finalwrite[$z] = $writevalue;
$x = $x + 2;
$y = $y + 2;
$z++;
}
seek FILE, 0, 0;
Don't use magic numbers, use constants.
use Fcntl qw/:seek/;
seek $FILE, 0, SEEK_SET;
truncate FILE, 0;
print FILE @finalwrite;
Since you haven't set $,, this will print the array elements all on one
line, separated by spaces. I don't think that's what you meant.
Ben
--
I must not fear. Fear is the mind-killer. I will face my fear and
I will let it pass through me. When the fear is gone there will be
nothing. Only I will remain.
benmorrow@xxxxxxxxxxxxx Frank Herbert, 'Dune'
.
- Follow-Ups:
- Re: string retrieval issue
- From: Dr.Ruud
- Re: string retrieval issue
- From: John W. Krahn
- Re: string retrieval issue
- References:
- string retrieval issue
- From: mbliven1
- Re: string retrieval issue
- From: Paul Lalli
- Re: string retrieval issue
- From: mbliven1
- string retrieval issue
- Prev by Date: Re: string retrieval issue
- Next by Date: Re: string retrieval issue
- Previous by thread: Re: string retrieval issue
- Next by thread: Re: string retrieval issue
- Index(es):
Relevant Pages
|
|