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

I have an address book program I am writing in Perl. Someday it will write to a database program but for the moment it writes to a .txt file.

It will not accept more than one pass of information, only the last information entered will be written. While I "sort of" understand this I don't know what to do about this. Further I don't know where to look to fix it. Here is an abbrieviated version of the current code.
#! /usr/local/bin/perl -w use strict ; #Adress Book Program print "Address Book Program v .03\n\n" ; open (ADDRESS, '>> addbook.txt') or die "Can't open file; $!" ; my ($cat, $fname, $lname, $cname, $addr1, $addr2, $field, $value) ; my $quit = 0 ; while ($quit != 1) { print "Is this a Personal or Business contact? (Enter P or B)" ; my $perbus = <STDIN> ; chomp $perbus ; if ($perbus eq 'b'){ $cat = "Business" ; } else { $cat = "Personal" ; } print "Enter a first name: " ; $fname = <STDIN> ; chomp $fname ; print "Enter a last name: " ; $lname = <STDIN> ; chomp $lname ; print "Enter address information: " ; $addr1 = <STDIN> ; chomp $addr1 ; print "Enter address information: " ; $addr2 = <STDIN> ; chomp $addr2 ; print "Do you want to enter another address? (Y or N) " ; my $ans = <STDIN> ; chomp $ans ; #checks for Y or y if ($ans !~ m/[Yy]/) { $quit = 1 ; } else { $quit = 0 ; } } my @lines = ( [ "NAME", "$lname, $fname" ], [ "ADDRESS", $addr1 ], [ "ADRESSS", $addr2 ], for (@lines) { ($field, $value) = @$_ ; write ADDRESS ; } close ADDRESS or die "Can't close file; $!" ; format ADDRESS_TOP = AddressBook version 0.03 ___________________ ______________________________________________ +________ . format ADDRESS = @<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +<<<<<<<< $field, $value .
So what is wrong? Where/how should I look to fix this?
--
ellem@optonline.net
There's more than one way to do it, but only some of them actually work.

Edit kudra, 2002-05-07 Changed title

  • Comment on Program only writes last information entered (was Writing and writing and writing)
  • Download Code

Replies are listed 'Best First'.
Re: Writing and writing and writing
by japhy (Canon) on May 07, 2002 at 12:37 UTC
    You're not calling write() until you're done with the loop. You need to call write() at the end of every iteration, so that each block of data gets written.

    _____________________________________________________
    Jeff[japhy]Pinyan: Perl, regex, and perl hacker, who'd like a (from-home) job
    s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;

Re: Writing and writing and writing
by graff (Chancellor) on May 07, 2002 at 14:12 UTC
    Alternatively to japhy's suggestion, move the declaration for @lines up above the while loop, and push the values of $lname, $fname, etc, onto the array during each iteration of the loop. As you have it written at present, @lines contains only the last set of values that was entered. So:
    my @lines; my $quit = 0; ... until ($quit ) { ... push( @lines, ... ); $quit = ( $ans =~ /^n/i ); } foreach (@lines) { ... write ADDRESS; }
    UPDATE: Another alternative, which would make this sort of program a lot easier to use: some Tk widgets. E.g. a pair of radio buttons for business vs. personal, four entry boxes for the names and address stuff, a "Store it" button, an "Exit" button... heck, why not a "Show list" button with a pop-up text widget, so the user can see who's on the list already. More features will come to mind (this can become addictive). You do have the Tk modules, don't you?
Re: Writing and writing and writing
by DigitalKitty (Parson) on May 07, 2002 at 14:42 UTC
    Hi.

    These are largely cosmetic enhancements but you could shorten the lines that look like this:
    print "Enter a first name: " ; $fname = <STDIN> ; chomp $fname ;

    to this:

    print "Enter a first name: "; chomp($fname = <STDIN>);


    Also, if a user types "yes", "yep", or some other variation, you might want to alter this line:
    if ($ans !~ m/[Yy]/) { $quit = 1 ; } else { $quit = 0 ; }


    to this:
    if( $answer =~ /^[Yy]/) . . . .

    This way, if the input starts with a Y or y, it will be considered valid ( true ). Hope this helps,

    -Caitlin