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

When using printf "%.1f", $var ; How do I get the output to include a ',' as the decimal separator and not a '.'. If $var is a real number from a db and for example is 10.5 I want it to print 10,5 not 10.5. The output is being opened by an Excel file from a web page. This script is being used in Finland where ',' is used as the decimal point. And '.' is the date separator. If Excels sees 10.5 it thinks it is the 10th of May :( Thanks Scott

Replies are listed 'Best First'.
(crazyinsomniac) Re: Using printf with %.1f
by crazyinsomniac (Prior) on Aug 07, 2001 at 09:43 UTC

    POD to the rescue

    where did you look?

    perldoc -f printf printf FILEHANDLE FORMAT, LIST printf FORMAT, LIST Equivalent to "print FILEHANDLE sprintf(FORMAT, LIST)", ex +cept that "$\" (the output record separator) is not appended. T +he first argument of the list will be interpreted as the "pri +ntf" format. If "use locale" is in effect, the character used f +or the decimal point in formatted real numbers is affected by the LC_NUMERIC locale. See the perllocale manpage. Don't fall into the trap of using a "printf" when a simple "print" would do. The "print" is more efficient and less e +rror prone. perldoc perllocale Category LC_NUMERIC: Numeric Formatting In the scope of use locale, Perl obeys the LC_NUMERIC locale informati +on, which controls an application's idea of how numbers should be for +matted for human readability by the printf(), sprintf(), and write() +functions. String-to-numeric conversion by the POSIX::strtod() functi +on is also affected. In most implementations the only effect is to ch +ange the character used for the decimal point--perhaps from '.' to ', +'. These functions aren't aware of such niceties as thousands separat +ion and so on. (See The localeconv function if you care about these t +hings.) Output produced by print() is also affected by the current locale: it +depends on whether use locale or no locale is in effect, and correspo +nds to what you'd get from printf() in the ``C'' locale. The same is +true for Perl's internal conversions between numeric and string forma +ts: use POSIX qw(strtod); use locale; $n = 5/2; # Assign numeric 2.5 to $n $a = " $n"; # Locale-dependent conversion to string print "half five is $n\n"; # Locale-dependent output printf "half five is %g\n", $n; # Locale-dependent output print "DECIMAL POINT IS COMMA\n" if $n == (strtod("2,5"))[0]; # Locale-dependent conversion

     
    ___crazyinsomniac_______________________________________
    Disclaimer: Don't blame. It came from inside the void

    perl -e "$q=$_;map({chr unpack qq;H*;,$_}split(q;;,q*H*));print;$q/$q;"

Re: Using printf with %.1f
by dga (Hermit) on Aug 07, 2001 at 09:34 UTC

    Perhaps a locale setting from one of the POSIX:: modules might help? I haven't used locale stuff but it may do exactly the desired thing.

    Also you could use sprintf instead of printf and then fix up the result. Like:

    #(other program stuff here) my $a=10.5; my $str=sprintf "%.1f",$a; $str =~ s/\.(\d)$/,$1/; #only do the last . and preserve the digit print $str; #(and more program stuff here)

    Of course some of the lines could be collapsed together to make it less lines of code.

Re: Using printf with %.1f
by jlongino (Parson) on Aug 07, 2001 at 09:24 UTC
    alexsc01,

    Use a custom format sub such as the following I wrote:

    my $num = 244.83; print "'" . str($num, 8, 3) . "'\n"; sub str { ## This sub is used to return a formatted numeric string. ## It has three arguments which are: the number sent, the ## desired width (including decimal point, if any), and ## the number of decimal places (optional) in that order. ## The number is right-justified. my ($sentnum, $width, $precision) = @ARG; ## Check to see if a non-zero precision was sent. if ($precision) { ## print to var using decimal point. $sentnum = sprintf("%" . "$width.$precision" . "f", $sentnum); } else { ## print in integer format. $sentnum = sprintf("%" . "$width.0" . "f", $sentnum); } ## change decimals to commas $sentnum =~ tr/./,/; return $sentnum; }
    Hope this helps.

    Update: could move tr/./,/ to above else statement.
    Results: ' 244,830'