16

我有一些十进制数字需要在适当的时候写入带有前导零的文本文件。我对此进行了一些研究,我所看到的一切都表明:

  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 < VALUE < 1000 的所有值。如果我设置VALUE = 12.3456,上面的代码应该产生“012.3456”作为输出,它确实如此。但是,如果我有类似的东西VALUE = -12.3456,我会得到“(3个星号).3456”作为我的输出。我知道当语句中没有提供足够的字符时,通常会出现星号FORMAT,但是在这个例子中 3 个应该就足够了(“-”有 1 个字符,“12”有两个字符)。我还没有用类似的东西对此进行测试VALUE = -9.876,但我希望输出为“-09.8760”。

我对它的工作原理的理解有什么问题吗?还是我违反了这种技术的其他限制?

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

4

3 回答 3

17

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

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

但最后,你可能只是想要这个:WRITE(*,'(f0.3)') VALUE

于 2013-01-29T18:14:19.707 回答
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块或复杂的光标移动,如果可能的话,我想避免这种情况。

于 2013-01-29T18:19:23.873 回答
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
于 2013-01-29T19:07:12.037 回答