Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

increment # but keep # of digits same

by yankeeblue (Novice)
on Apr 26, 2005 at 14:27 UTC ( [id://451590]=perlquestion: print w/replies, xml ) Need Help??

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

Hello, I have a dilemma involving updating a build number in a .rc2 file. I have other scripts that update the build number fine, but this one is different as I need the number to always remain 4 digits. The lines involving the build number are:

VALUE "FileVersion", "0001.0000.0000.0001\0"

VALUE "ProductVersion", "0001.0000.0000.0001\0"

I need to bump up the last number in the last set of numbers, i.e. the first build would bump .0001\0" to .0002\0". I know how to do that. My problem occurs because that last set of numbers, .0001, needs to always remain 4 digits, never more. So for example build number 10 would need to look like:

VALUE "FileVersion", "0001.0000.0000.0010\0"

VALUE "ProductVersion", "0001.0000.0000.0010\0"

For my other builds, it's easy, there is no restriction on the number of digits. For example I do the following (sorry if the code isn't the most efficient, I'm fairly new to Perl):
## This is the line containing the build num from the file $buildnumfi +le2. ## [assembly: AssemblyFileVersion("1.0.0.408")] ### Opens the buildnum file for input. tie @array2, 'Tie::File', $buildnumfile2 or die "Cannot open build number file: $!"; $num_files = @array2; for ($p=0; $p<$num_files; $p++) { $file = $array2[$p]; if ($file =~ /(AssemblyFileVersion)\(("([^"]*)")\)\]/) { $relnumber2 = $3; #1.0.0.1 @nums2 = split /\./, $relnumber2; $lastbldnumber2 = $nums2[3]; $newbldnumber2 = $lastbldnumber2 + 1; } } ### Now replace the old build number with the new build number. for (@array2) { s/(AssemblyFileVersion)(\("$nums2[0]\.$nums2[1]\.$nums2[2]\.$lastbld +number2"\))/AssemblyFileVersion\("$nums2[0]\.$nums2[1]\.$nums2[2]\.$n +ewbldnumber2"\)/g; } $newrelnumber2 = join ".", $nums2[0], $nums2[1], $nums2[2], $newbldnum +ber2;
TIA for your help! Any advice is greatly appreciated.

Replies are listed 'Best First'.
Re: increment # but keep # of digits same
by ikegami (Patriarch) on Apr 26, 2005 at 14:33 UTC

    Use sprintf '%04d':

    $whole_number = '0001.0000.0000.0010'; $whole_number =~ s/(?<=\.)(\d+)$/sprintf('%04d', $1+1)/e; print($whole_number, "\n"); # 0001.0000.0000.0011
Re: increment # but keep # of digits same
by suaveant (Parson) on Apr 26, 2005 at 14:39 UTC
    You probably want sprintf, sprintf("%04d",$number) will return it in a 4 digit number padded by zeros, then you can do a test to see if the number is greater than 9999 and handle it according. also, ++ will maintain the zeros if they are in the variable... i.e.
    $a = '0001'; $a++; print $a; 0002
    then you can just use a regexp or substring to put chop and edit the version number.

                    - Ant
                    - Some of my best work - (1 2 3)

Re: increment # but keep # of digits same
by duff (Parson) on Apr 26, 2005 at 14:42 UTC

    There are two ways to accomplish what you want that immediately come to mind: use sprintf() to ensure the proper number of digits and use the magic increment. The first way is simply $newbuildnum = sprintf("%05d", $oldbuildnum+1) Adjust the 5 as needed. %05d is a format specifier that says output an integer that has a width of 5 characters and is 0 padded.

    The second method is kind of sneaky. When you have a variable that holds a string, for instance, $a= "foo" and you do $a++, perl will turn that "foo" into "fop". Another $a++ will get you "foq" and so on. This behavior continues wrapping around at "z" (i.e., $a = "foz"; $a++; would result in $a = "fpa") When the string consists of numbers, perl does the same thing only wrapping at "9". Thus:

    #!/usr/bin/perl $a = "00001"; for (0..20) { print $a; $a++ } __END__ 00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 00013 00014 00015 00016 00017 00018 00019 00020 00021

      That could simply be:

      #!/usr/bin/perl foreach("00001".."00021"){ print "$_\n"; }

      Edit: Just showing that the increment operator is a bit magical, but now I see I've probably missed the point a bit.

      -Any sufficiently advanced technology is
      indistinguishable from doubletalk.

      My Biz

Re: increment # but keep # of digits same
by Fletch (Bishop) on Apr 26, 2005 at 14:33 UTC
    perldoc -f sprintf
Re: increment # but keep # of digits same
by brian_d_foy (Abbot) on Apr 26, 2005 at 18:55 UTC

    What happens if you get to 9999? Do you wrap around? (If you don't get that high, you can probably ignore this post).

    When the number goes past 9999, you can get the last four digits with the modulus operator ( $i % 10_000). However, for 10_000, you end up with 0, which may not make sense (but you just treat it as a special case and set it to 1).

    You can't simply use sprintf() as others have suggested. A %4d format specifier does not limit the field to four columns: it only tries to set it in a four column field and it can overflow. It does not guarantee output of a particular width.

    --
    brian d foy <brian@stonehenge.com>
      $width = 4; $number = substr(sprintf("%0${width}d", $number + 1), -$width);
Re: increment # but keep # of digits same
by yankeeblue (Novice) on Apr 27, 2005 at 13:07 UTC

    Thanks everyone for your replies. I ended up using sprintf because using $a++ wasn't working in my if conditional (to check if the number was less than 9999). For some reason when I had $a++ within the if, it was losing the 4 digits and coming back as just 2, vs. 0002. Outside of the if it was fine. sprintf seems to be working OK with the if however. Thanks again, I appreciate everyone's help.

    Incidentally, if the number is >=9999, I just reset the build number back to 0. I honestly don't think the build number will ever get that high, but I put the check in there just in case.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://451590]
Approved by Bukowski
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (3)
As of 2024-04-24 00:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found