2014-08-28 158 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

相關問題