On 2/6/10, Chris Coggins <cacogg...@cox.net> wrote: > Rob Dixon wrote: >> Chris Coggins wrote: >>> I posted a question to this list yesterday from the google groups >>> interface, asking for help with the following. I have since tried to >>> post additional details in replies to that message using the google >>> groups site and none of my posts have shown up on the list so let's >>> try this again the right way. >>> >>> I have a datafile with 1 line of data, 30 numbers delimited by >>> tildes. (Sample code below only uses 4 numbers to save time) >>> >>> I need to open this file, grab this line of data, split it into >>> individual numbers, perform some simple math (addition) on each >>> number, and then put the new values back into the datafile, replacing >>> the original data that was there. >>> >>> I neglected to mention in my original post that I need to access >>> these new values elsewhere in the script to perform additional math >>> functions with them. >>> >>> I've tried several variations of the code below, including using >>> arrays, and none of them got through without the script failing. The >>> new datafile gets written, but it merely contains a ~. The errors I >>> get are "use of uninitialized values in such and such line" and >>> "variables needs explicit package name". When the script does run, >>> the variables lose their values as soon as I close the file after >>> inhaling it, making all the rest of the actions in the subroutine >>> futile. >>> >>> the datafile used below initially contains 30 values that were >>> written previously, and this has been verified over and over. >>> >>> sub newValues { >>> my($file) = shift; >>> >>> open(FILE, "<$file") or die("Unable to open data file."); >>> while (<FILE>) { >>> my($a,$b,$c,$d) = split(/~/, $_); >>> $a = $a+$previousarray[4]; # I've tried to perform this math action >>> after close(FILE) and get the same result -> failure. >>> $b = $b+$previousarray[7]; >>> $c = $c+$previousarray[0]; >>> } >>> close(FILE); >>> open(FILE, ">$file") || die ("unable to open file"); >>> print FILE ("$a~$b~$c \n"); >>> close(FILE); >>> } >>> #end sub >>> >>> Now my datafile just contains a single tilde and no values. I've also >>> tried to bring the original data from the datafile into my(@array) >>> and get the same errors. >>> >>> Keep in mind I need other subroutines to be able use these new >>> values, but these local variables lose their values once the file is >>> closed. I've also tried to declare them as global variables but I'm >>> not doing something right because the script won't execute. >>> >>> I really need some help figuring this out if somebody would be kind >>> enough to help a novice. >> >> Hello Chris >> >> Your lexical variables $a, $b, $c are local to the 'while' block, and >> do not exist outside it. Error "Global symbol xx requires explicit >> package name" is because the variable is not declared. Error "Use of >> uninitialized value..." is because Perl uses a value of 'undef' where >> variables are missing. >> >> As an aside it is bad form to use meaningless variable names, and $a >> and $b are special names that are used by core Perl so should be >> avoided. Also it is prefereable to use lexical file handles and the >> three-argument form of 'open', and incorporating the standard variable >> $! into the die string will give valuable information about why the >> operation failed. >> >> Declaring your variables outside the 'while' loop would fix your >> problem, but as you are interested only in the first line of the file >> it is as well to remove the loop altogether. Take a look at the code >> below and see if it meets your requirements. >> >> HTH, >> >> Rob >> >> >> sub newValues { >> >> my $file = shift; >> >> open my $data, '<', $file or die "Unable to open data file: $!"; >> my $line = <$data>; >> close $data; >> >> my @data = split /~/, $line; >> die "Invalid data format" if @data < 3; >> $data[0] += $previousarray[4]; >> $data[1] += $previousarray[7]; >> $data[2] += $previousarray[0]; >> >> open my $out, '>', $file or die "Unable to open output file: $!"; >> print $out join('~', @data[0,1,2]), "\n"; >> close $out or die "Failed to close output file: $!"; >> } >> > Rob, thank you very much. This worked perfectly, unless my datafile is > empty at the start. Easiest fix was inserting 30 zero-tildes into the file. > > I have a couple other snags if yall are willing to tolerate the questions. > > 1. another script uses data passed into it from an html form. Some of > the fields are empty, and my "print report file" subroutine prints the > empty variables because I don't know how to filter them out, and they > need to be removed from the report. Can someone give me the perfectly > formed "if" statement that lets me skip over the one or two empty > variables during the print action? The data being printed to the file is > stored in an array. See code below. > > print FILE ("Report summary: $taskarray[0] \n"); #this value is good > print FILE ("Data for task 3: $taskarray[3] \n"); #this value is good > print FILE ("Data for task 7: $taskarray[7] \n"); #this value is empty, > don't print this data > print FILE ("Data for task 2: $taskarray[2] \n"); #this value is empty, > don't print this data > print FILE ("Data for task 11: $taskarray[11] \n"); #this value is good > but needs to be modified, see #2 below > > 2. Some of the data being printed above needs to be stripped of some of > its characters in the string. For example, one of the values is a part > number with 27 characters. I only need the last 10 characters of the > string for this report because somebody else is going to fill in the > front 17 characters with a new part code that I have nothing to do > with. The string currently looks like this: > TNA-140ZQ00-170011234567.890. I need it to print to FILE like this: > ___-_______-______1234567.890, and I need to do this in the same block > of code above. > > Chris
1) You would have to be more specific as to what an 'empty variable' is. Zero? A blank string? undef? 2) use strict; use warnings; use 5.010; my $string = 'TNA-140ZQ00-170011234567.890'; my $prefix = '___-_______-______'; my $last_eleven = substr $string, -11; say "$prefix$last_eleven"; --output:-- ___-_______-______1234567.890 By the way, you should know that a period is a character. You are pretty sloppy in describing your problems. Consider providing *no* verbal explanation of your problems. Rather try posting, "I have xxxx and I am trying to get yyyy". Here is an example program demonstrating what I am trying to do. My *expected* output (or error) is this. My *actual* output is this." Also, when you have a problem in your actual program, to try and solve it you should create another practice program. Try to mimic the problem with a 10 line example program, and then post your example program--not your real program. -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/