Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling

getting wrong value

by ggrise (Initiate)
on Jan 15, 2013 at 22:28 UTC ( #1013464=perlquestion: print w/replies, xml ) Need Help??
ggrise has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to convert a numbers in a file I have a line: $line2 = printf ("%#x", $line); $line for example is 55473 $line2 ends up containing a 1 not the 0xd8b1 I was expecting and when I run program I see the 0xd8b1 written to the screen, how do I get $line2 to have the 0xd8b1 value ?

Thanks a million to all for the sprintf answer and the other comments.

Getting printf to work was harder than sprintf, however was very educational.

I looked at Prototypes in perlsub and Far More than Everything You've Ever Wanted to Know about Prototypes in Perl -- by Tom Christiansen, I also looked at "perl in a nutshell" and "Perl 5 by Example" and didn't see what to do. Finally after a number of changes and web searches the following seems to work without the warnings " called too early to check prototype at and "use of unitialized value". I am assuming this is correctly coded?

documentation on prototypes is poor for a beginner (or at least me).

#!/usr/bin/perl # use warnings; use strict; use Carp (); local $SIG{__WARN__} = \&Carp::cluck; sub capture_stdout($) { my($v); my $line = shift; local *STDOUT; open(STDOUT, '>', \$v); printf ("%#x", $line); return $v; } open(MYINPUTFILE, "<test.dat"); open(MYOUTPUTFILE, ">hex.dat"); while(<MYINPUTFILE>) { my($line) = $_; my $line2 ; chomp($line); $line2 = capture_stdout($line) ; print MYOUTPUTFILE "$line2\n"; } close(MYINPUTFILE); close(MYOUTPUTFILE);

Replies are listed 'Best First'.
Re: getting wrong value
by AnomalousMonk (Canon) on Jan 15, 2013 at 22:54 UTC

    printf returns 1 for a successful print, which is what you say happens. You probably want sprintf (note leading 's'), which returns a string.


    >perl -wMstrict -le "my $line = 55473; my $line2 = sprintf '%#x', $line; printf qq{\$line is '%#x' \n}, $line; print qq{\$line2 is '$line2'}; " $line is '0xd8b1' $line2 is '0xd8b1'
      Thanks, that works. however if printf will print to STDOUT, why can't I get it to print to $line2 ?

        You can (since 5.8; see open, search for 'scalar'):

        >perl -wMstrict -le "my $scalar_as_file; ;; open my $fh_scalar, '>', \$scalar_as_file or die qq{opening: $!}; printf $fh_scalar q{xxx :%#x: yyy}, 55473; close $fh_scalar; ;; print qq{scalar as file: '$scalar_as_file'}; " scalar as file: 'xxx :0xd8b1: yyy'
Re: getting wrong value
by johngg (Abbot) on Jan 15, 2013 at 22:59 UTC

    You need sprintf to assign to a scalar. You are getting the value 1 in your $line2 variable as that is what is returned by the successful printf that displays on your screen.

    $ perl -E ' > my $line = 55743; > my $line2 = sprintf q{%#x}, $line; > say $line2;' 0xd9bf $

    I hope this is helpful.



Re: getting wrong value
by AnomalousMonk (Canon) on Jan 16, 2013 at 01:34 UTC

    From the updated OP:

    $line2 = capture_stdout($line) ; ... sub capture_stdout() { ... }

    The function  capture_stdout() { ... } is prototyped to take no arguments and is called with one argument (which is not used!), but the code is executed in such an order as to avoid prototype checking. I suspect the code is also being run without warnings, thus avoiding the "function name called too early to check prototype..." message.

    pvaldes has pointed out the way to explicitly defeat prototype checking, but if you're going to avoid or defeat prototype checking, why bother to use prototyping in the first place?

    Please see Prototypes in perlsub and Far More than Everything You've Ever Wanted to Know about Prototypes in Perl -- by Tom Christiansen – and then don't use prototypes unless you really need to and really understand their intended usage.

Re: getting wrong value
by pvaldes (Chaplain) on Jan 16, 2013 at 00:21 UTC

    And you are not calling the function

    open(INFILE, '<','test.dat'); open(OUTFILE, '>','hex.dat'); while(<INFILE>){ chomp; #printf ("%#x", $line) > $line2; my $line2 = &capture_stdout($_) ; ### <--- see the & print OUTFILE $line2,"\n"; } sub capture_stdout(){ my $v; local *STDOUT; open(STDOUT, '>', \$v); printf ("%#x", $_); return $v; } close INFILE; close OUTFILE;

    In any case you can use pack for this, probably

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1013464]
Approved by johngg
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (9)
As of 2017-02-27 09:45 GMT
Find Nodes?
    Voting Booth?
    Before electricity was invented, what was the Electric Eel called?

    Results (378 votes). Check out past polls.