我有一些十进制数字,我需要在适当的时候写入带有前导零的文本文件。我对此做了一些研究,我见过的所有内容都表明:
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”为2个字符)。我还没有测试过类似的东西 VALUE = -9.876
,但我希望输出为“-09.8760”。
我对这是如何工作的理解有什么不对吗?或者我违反了这项技术还有其他一些限制吗?
更新:好的,我已经对此进行了更多研究,它似乎是一个负值和一个组合 I3.3
格式。如果VALUE为正,我有 I3.3
,它将按预期放置前导零。如果VALUE为负数且我只有 I3
作为我的格式,我得到正确的值输出,但它会在负号之前用空格填充,而不是在负号之后用零填充(所以-9.8765输出为“-9.8765”,但是那个领先的空间打破了我的' m使用.txt文件,所以这是不可接受的)。
问题在于整数数据编辑描述符。同 I3.3
你需要至少3位数,字段宽度只有3.没有减号的地方。使用 I4.3
或者,在Fortran 95及以上版本中, I0.3
。
回答你的编辑:使用 I0.3
,它使用必要的最少字符数。
但最后,你可能想要这个: WRITE(*,'(f0.3)') VALUE
当然,我可以通过改变它来获得我正在寻找的东西
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
块或复杂的光标移动,如果可能的话我想避免。
作为皮肤猫的另一种方式..我宁愿不对数据进行算术运算,只需要处理格式:
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