2010-03-21 2 views
1

J'ai des problèmes pour écrire des données dans un fichier en utilisant Perl.Comment écrire dans le même fichier dans différents sous-programmes de Perl?

sub startNewOrder{ 
    my $name = makeUniqueFileName(); 
    open (ORDER, ">$name.txt") or die "can't open file: $!\n"; 
    format ORDER_TOP = 
    PRODUCT<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<CODE<<<<<<<<AANTAL<<<<EENHEIDSPRIJS<<<<<<TOTAAL<<<<<<< 
. 
    format ORDER = 
    @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<< @<<<< @<<<<<< @<<<<< 
    $title,        $code, $amount, $price, $total 
. 
    close (ORDER); 
} 

Ceci est le sous-élément que j'utilise pour créer le fichier. (J'ai traduit la plupart de celui-ci.) La méthode makeUniqueFileName crée un nom de fichier basé sur l'heure actuelle ("minuteshoursdayOrder"). Le problème maintenant est que je dois écrire dans ce fichier dans un autre sous.

sub addToOrder{ 
print "give productcode:"; 
$code = <STDIN>; 
chop $code; 
print "Give amount:"; 
$amount = <STDIN>; 
chop $amount; 
if($inventory{$code} eq undef){ #Does the product exist? 
    print "This product does not exist"; 
}elsif($inventory{$code}[2] < $amount && !defined($inventaris{$code}[2])){ #Is there enough in the inventory? 
    print "There is not enough in stock" 
}else{ 
    $inventory{$code}[2] -= $amount; 
    #write in order file 
    open (ORDER ">>$naam.txt") or die "can't open file: $!\n"; 
    $title = $inventory{$code}[0]; 
    $code = $code; 
    $amount = $inventory{$code}[2]; 
    $price = $inventory{$code}[1]; 
    $total = $inventory{$code}[1]; 
    write; 
    close(ORDER); 
} 

%inventory est un Hashtable qui a la productcode comme clé et un tableau avec le titre, le prix et le montant en tant que valeur. Il y a deux problèmes ici: quand j'entre un numéro de produit invalide, je dois encore entrer une quantité même si mon code indique qu'il devrait imprimer l'erreur directement après avoir vérifié s'il y a un produit avec le code donné.

Le deuxième problème est que l'écriture ne semble pas fonctionner. Il donne toujours une erreur "No such file or directory". Y at-il un moyen d'ouvrir le fichier ORDER que j'ai fait dans le premier sous sans avoir à faire $name pas local? Ou juste un moyen d'écrire dans ce fichier? Je ne sais vraiment pas comment commencer ici. Je ne peux pas vraiment trouver beaucoup d'informations sur l'écriture d'un fichier qui a été fermé auparavant, et dans un autre sous.

Toute aide est appréciée,

Harm

Répondre

4

Vous devriez commencer par l'ajout de ces lignes à votre code:

use strict; 
use warnings; 

Ils vont attraper les fautes de frappe potentiels. Par exemple, $inventaris est une variable différente de $inventory. Vouliez-vous vraiment avoir deux variables? C'est difficile à dire de votre code. De même, avez-vous vraiment une variable nommée $naam?

Oui, il est possible d'écrire dans un fichier à partir de 2 sous-programmes distincts. Actuellement, $name est local à votre startNewOrder. Une façon de le rendre visible à votre autre sous est de le déclarer au début de votre code, le rendant global à votre fichier de code. Pouvez-vous déplacer votre format dans le même sous-marin que votre write? Dans votre code, il est plus approprié d'utiliser chomp au lieu de chop.

Il est préférable de vérifier l'existence d'une clé de hachage en utilisant exists que de la comparer à la valeur renvoyée par undef.

use strict; 
use warnings; 

my $name = makeUniqueFileName(); 

# Sample data 
my %inventory = (
    c1 => [ 1 .. 3 ], 
    c2 => [ 4 .. 6 ] 
); 

addToOrder(); 

sub addToOrder { 
    print "give productcode:\n"; 
    my $code = <STDIN>; 
    chomp $code; 
    print "Give amount:\n"; 
    my $amount = <STDIN>; 
    chomp $amount; 
    if (not exists $inventory{$code}) { 
     print "This product does not exist\n"; 
    } 
    # etc... 
} 

Je réalise que je n'ai pas répondu à toutes vos questions. Vous pourriez peut-être vous concentrer sur une question à la fois et fournir un exemple autonome et exécutable avec un petit échantillon de données réelles. Je résous souvent mes propres problèmes en réduisant mon code à un exemple minimal qui reproduit toujours le problème.

2

Les sous-programmes doivent faire le moins de travail possible et garder la plus petite portée possible. Dans votre cas, vous ne voulez pas avoir à ouvrir un fichier dans chaque sous-programme. Ouvrez le fichier une fois et passez le handle de fichier ouvert. Vous n'avez pas à fermer et rouvrir le fichier à chaque fois.

Puisque vous voulez utiliser des formats, vous devez utiliser bareword de descripteurs de fichiers:

my $name = makeUniqueFileName(); 
open ORDER, '>', $name or die ...; 

start_new_order(\*ORDER); 
add_to_order(\*ORDER); 

sub start_new_order { 
     local *ORDER = shift; 
     ... 
     write ORDER; 
     } 

sub add_to_order { 
     local *ORDER = shift; 
     ... 
     write ORDER; 
     } 

Vous pouvez définir vos formats partout. Vous n'avez pas à les définir dans le sous-programme, il suffit donc de les mettre à la fin du fichier.

Questions connexes