2014-08-28 157 views
1

有没有办法改变逗号的句号小数点分隔符?Fortran小数点和千位分隔符

另外,我怎样才能使输出数字有千位分隔符?打开文件

open(100,file=logfile,status='unknown',DECIMAL='COMMA') 

时,这可能是一个逗号,句号,空间...

+1

我居然问类似的问题:http://stackoverflow.com/a/21117594/ 2432130 – 2014-08-28 11:55:24

+0

@AlexanderVogt @Alex区别在于千位分隔符,这有点棘手。 POSIX语言环境知道它,但C'printf'和'sprintf'忽略它。 – 2014-08-28 13:09:12

+0

好吧,@Alex,所以这个:'write(*,'(dc,f12.3)')12.3'设置我想要的小数点分隔符。但仍然是千位分隔符问题。 – 2014-08-29 10:26:14

回答

3

使用参数DECIMAL =“逗号”这将小数点改为逗号

+2

是的,但是,如果我想在屏幕上打印数字呢?那千位分隔符呢? – 2014-08-28 11:08:06

4

你可以编写一个C++函数,它可以将当前语言环境中的字符串中的数字转换为您的数字。

#include <string> 
#include <iomanip> 
#include <sstream> 

class SpaceSeparator: public std::numpunct<char> 
{ 
public: 
    SpaceSeparator(std::size_t refs): std::numpunct<char>(refs) {} 
protected: 
    char do_thousands_sep() const { return ' '; } 
    char do_decimal_point() const { return ','; } 
    std::string do_grouping() const { return "\03"; } 
}; 

extern "C" { 

void convert(char* str, double f, int len) { 
    std::string s; 
    std::stringstream out; 
    SpaceSeparator facet(1); //1 - don't delete when done 
    std::locale prev = out.imbue(std::locale(std::locale(), &facet)); 
    out << std::setprecision(15) << f; 

    s = out.str(); 
    std::copy(s.begin(), s.end(), str); 
    int i; 
    for (i=s.size();i<len;i++){ 
    str[i] = ' '; 
    } 
} 

} 

呼叫从Fortran语言:

use iso_c_binding 

    interface 
    subroutine convert(str, f, l) bind(C,name="convert") 
     import 
     character(c_char) :: str(*) 
     real(c_double), value :: f 
     integer(c_int), value :: l 
    end subroutine 
    end interface 

    character(len=100,kind=c_char) :: ch 

    call convert(ch, 123456.123_c_double, len(ch, kind=c_int)) 
    print *,ch 
end 

在我的机器它打印123 456,123

> gfortran locale.cc locale.f90 -lstdc++ 
> ./a.out 
123 456,123         

免责声明:我不是一个C++程序员,他的解决方案可能会很慢。也许Fortran的强力方法更好。

我用这个答案作为基础:https://stackoverflow.com/a/2648663/721644

+0

谢谢。但我想我会尝试一个更多的Fortran_方法,在Fortran中编写我自己的函数来管理小数点和千位分隔符。 – 2014-08-29 09:53:39

+0

@AntonioSerrano你可以从乔治的答案开始。 – 2014-08-29 10:22:00

2

一个快速和肮脏的FORTRAN为基础的方法:

implicit none 

    write(*,*) commadelim(123456.789) 
    write(*,*) commadelim(23456.789) 
    write(*,*) commadelim(3456.789) 
    write(*,*) commadelim(-123456.789) 
    write(*,*) commadelim(-23456.789) 
    write(*,*) commadelim(-3456.789) 

    contains 

    function commadelim(v) 
     implicit none 

     real v 
     integer dp,p,z0,i 
     character(len=50) :: commadelim 

     write(commadelim,'(f0.12)') abs(v)  
     dp = index(commadelim,'.') 
     commadelim(dp:dp) = ',' 
     z0 = 2 - mod(dp+1,3) 

     do i = 1, (dp+z0-1)/3-1 
     p = 4*i-z0 
     commadelim = commadelim(:p)//'.'//commadelim(p+1:) 
     enddo 

     if (v<0) commadelim = '-'//commadelim 
    end function 
    end 
+1

+1,但是我在代码中添加了一些格式,如果您不喜欢它的某些部分,则可以恢复它。 – 2014-08-28 20:24:54

+0

我真的不明白这段代码,但现在我意识到它可以处理两个千位分隔符和小数点分隔符。 – 2014-08-29 11:38:49

+0

哪个更有效率,这个代码还是C++代码? – 2014-08-29 11:39:27

相关问题