Thank you... I suppose I should be ashamed that I wrote a 300 line script that didn't work while corian made one that worked in 20 lines...
I was trying indeed to find a way around all that repitition. I know c fairly well, and beleive me, I don't write c like that. But I couldn't figure out how to save all of those in one variable. I was thinking about an array, but I'm just not yet comfortable enough with perl to scripts a function to do that, etc.
Thanks again.
-Jack C
jack@crepinc.com | [reply] |
Well, I've used the code corian posted. And, o course, it works perfectly. Except, I edited it in places, and now wierd stuff happens. :(.
Basically, when I use the -c or -r option, it works great. But when I use the -a option, it tells me I've left off the option, but doesn't give me the error until AFTER it prints SOME of the data. Strange.
The other thing is, why does the order change everytime the script is run?
#!/usr/bin/perl -w
use strict;
my $infile = $ARGV[0];
my $act = $ARGV[1];
my $included = "n";
my $lvar ="";
my @validchars = ("A", "B", "C", "D", "E", "F", "G", "H",
"I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S",
"T", "U", "V", "W", "X", "Y", "Z");
if ($#ARGV < 1) {
print "Usage: $0 <file> <chars>
Where <chars> can be -a or -c:
-a: show all charactors. (ie, spaces, etc.)
-c: show only regular charactors, but keep case. (ie, x is diff
+erent than X.)
-r: show only regular charactors, disregard case. (ie, t and T
+are the same.)\n";
exit;
}
my $count = 0;
system("cls"); #win
system("clear"); #*nix
open INPUT, "<$infile" or die "Couldn't open '$infile' : $!";
my $input = do { local $/; <INPUT> };
my %histogram;
for my $char (split //, $input) {
$included = "n";
if ($act eq "-a") {
$histogram{$char}++;
$count++;
} elsif ($act eq "-c") {
foreach $lvar (@validchars){
if ($lvar eq uc($char)) {$included = "y";}
}
if ($included eq "y") {
$histogram{$char}++;
$count++;
}
} elsif ($act eq "-r") {
foreach $lvar (@validchars){
if ($lvar eq uc($char)) {$included = "y";}
}
if ($included eq "y") {
$histogram{uc($char)}++;
$count++;
}
} else {
print "Bad charactor option: '$act'.\n";
exit;
}
};
print "Of $count charactors:\n\n";
for (keys %histogram) {
if ($_ eq "\n") { print "'\\n' occurred $histogram{$_} times. (".(($
+histogram{$_}/$count)*100)."%)\n"}
else { print "'$_' occurred $histogram{$_} times. (".(($histogram{$
+_}/$count)*100)."%)\n" }
};
Thanks again,
-Jack C
jack@crepinc.com | [reply] [d/l] |
for (sort keys %histogram) {
...
};
I find a style issue with your @validchars usage - normally, if you want to quickly check whether something is contained in a list in Perl, you use a hash:
my %validchars = map { $_ => uc $_ } (qw( A B C D E F ... Z a b c d ..
+. z ));
# this sets
# $validchars{A} = A
# ...
# $validchars{Z} = Z
# $validchars{a} = A
# ...
# and the later:
if (exists $validchars{$_}) {
my $target = $validchars{$_};
$histogram{$target}++
};
For your different switches, you should simply initialize %validchars to different values instead of rechecking your switch values every time. This will clean up your inner loop as the program behaviour is centralized.
my %validchars;
if ( $arg eq '-a' ) {
%validchars = map { $_ => uc $_ } ( \x00 .. \xff );
} elsif ( $arg eq '-c' ) {
%validchars = map { $_ => $_ } ( 'A' .. 'Z', 'a'..'z' );
};
Whenever you are repeating code, think about how you can avoid that repetition. | [reply] [d/l] [select] |
There is no shame in learning something. The shame is if you don't learn it.
| [reply] |