Fortran中带有前导零的格式化输出

时间:2013-01-29 17:36:15

标签: formatting fortran

我有一些十进制数字,我需要在适当的时候写入带有前导零的文本文件。我已经对此做了一些研究,我见过的所有内容都表明:

  REAL VALUE
  INTEGER IVALUE

  IF (VALUE.LT.0) THEN
    IVALUE = CEILING(VALUE)
  ELSE
    IVALUE = FLOOR(VALUE)
  ENDIF
  WRITE(*,1) IVALUE, ABS(VALUE)-ABS(IVALUE)
1 FORMAT(I3.3,F5.4)

据我了解,IF块和ABS部分应该允许这适用于-100&lt; 1的所有值。值<&lt; 1000.如果我设置VALUE = 12.3456,上面的代码应该产生“012.3456”作为输出,它确实如此。但是如果我有类似VALUE = -12.3456的东西,我会得到“(3个星号).3456”作为我的输出。我知道当FORMAT语句中没有提供足够的字符时,通常会显示星号,但在本例中3应该足够了(“ - ”为1个字符,“12”为2个字符)。我还没有用VALUE = -9.876之类的东西对它进行测试,但我希望输出为“-09.8760”。

我对这种方法的理解是否有问题?或者我违反了这项技术还有其他限制吗?

更新:好的我已经对此进行了更多研究,它似乎是负值和I3.3格式的组合。如果VALUE为正且我有I3.3,它将按预期放置前导零。如果VALUE为负数且我只有I3作为我的格式,我得到正确的值输出,但它会在负号之前用空格填充,而不是在负数之后用零填充(所以-9.8765输出为“-9.8765”,但是那个领先的空间打破了我正在使用的.txt文件,所以这是不可接受的。)

3 个答案:

答案 0 :(得分:15)

问题在于整数数据编辑描述符。使用I3.3,您需要至少3位数字,字段宽度仅为3.减号没有位置。使用I4.3或在Fortran 95及更高版本中I0.3

回答您的修改:使用I0.3,它使用所需的最少字符数。

但最后,您可能想要这样:WRITE(*,'(f0.3)') VALUE

答案 1 :(得分:0)

当然,我可以通过将其更改为

来获得我正在寻找的东西
  REAL VALUE
  INTEGER IVALUE

  IF (VALUE.LT.0) THEN
    WRITE(*,1) FLOOR(ABS(IVALUE)), ABS(VALUE)-FLOOR(ABS(VALUE))
1   FORMAT('-',I2.2,F5.4)    
  ELSE
    WRITE(*,2) FLOOR(VALUE), ABS(VALUE)-FLOOR(BS(VALUE))
2   FORMAT(I3.3,F5.4)
  ENDIF

但是这感觉很笨拙,实际上我会尝试在同一行中写入多个值,这将导致非常混乱的IF块或复杂的光标移动,我会喜欢尽可能避免。

答案 2 :(得分:0)

作为皮肤猫的另一种方式..我宁愿不对数据进行算术处理,只需要处理格式:

character*8 fstring/'(f000.4)'/
val=12.34
if(val.gt.1)then
    write(fstring(3:5),'(i0)')6+floor(log10(val))
elseif(val.lt.-1)then
    write(fstring(3:5),'(i0)')7+floor(log10(-val))
elseif(val.ge.0)
    write(fstring(3:5),'(i0)')6
else
    write(fstring(3:5),'(i0)')7
endif
write(*,fstring)val

只是为了享受现代fortran的乐趣,它支持角色功能,你可以在一个函数中滚动它,最后得到这样的结构:

write(*,'('//fstring(val1)//','//fstring(val2)//')')val1,val2