我对Fortran 77有疑问,但我找不到解决方案。
我正在尝试存储一个字符串数组,定义如下:
character matname(255)*255
这是一个包含长度为255的255个字符串的数组。
后来我从文件中读取了名称列表,并按照以下方式设置了数组的内容:
matname(matcount) = mname
编辑:实际上,mname
值被编码为mname = 'AIR'
类型的character*255
,它是执行“{1}}的函数matadd()
的参数上一行。但这仅用于测试,将来它将从文件中读取。
后来我想打印出来:
write(*,*) matname(matidx)
但它似乎打印了所有255个字符,它打印我分配的字符串和大量垃圾。
感谢。
答案 0 :(得分:5)
您可以使用此功能获取长度(没有空白尾部)
integer function strlen(st)
integer i
character st*(*)
i = len(st)
do while (st(i:i) .eq. ' ')
i = i - 1
enddo
strlen = i
return
end
从这里得到:http://www.ibiblio.org/pub/languages/fortran/ch2-13.html
PS:当你说:matname(matidx)它得到整个字符串(256)字符...所以这是你的字符串加空格或垃圾
答案 1 :(得分:4)
Timotei发布的函数将为您提供字符串的长度,只要您感兴趣的字符串部分只包含空格,如果您在程序中分配值,则应该为true,因为FORTRAN应该是将变量初始化为空,对于表示空格的字符。
但是,如果您正在从文件中读入,则可能会在行尾添加其他控制字符(特别是回车符和/或换行符,\ r和/或\ n,具体取决于您的操作系统)。您还应该在函数中抛出这些以获得正确的字符串长度。否则你可以得到一些有趣的打印声明,因为这些字符也会被打印出来。
这是我的函数版本,它检查除空格之外的末尾的替换空白字符。
function strlen(st)
integer i,strlen
character st*(*)
i = len(st)
do while ((st(i:i).eq.' ').or.(st(i:i).eq.'\r').or.
+ (st(i:i).eq.'\n').or.(st(i:i).eq.'\t'))
i = i - 1
enddo
strlen = i
return
end
如果“垃圾”部分中还有其他字符,这仍然无法完全发挥作用。
假设它确实对您的数据有效,那么您可以将write语句更改为:
write(*,*) matname(matidx)(1:strlen(matname(matidx)))
它会打印出实际的字符串。
至于你是否应该使用另一个数组来保存字符串的长度,这取决于你。 strlen()函数是O(n),而查找表中的长度是O(1)。如果您发现自己经常计算这些静态字符串的长度,那么在读入它们时可能会提高计算长度的性能,将它们存储在数组中并在需要时查找它们。但是,如果你没有注意到减速,我不会担心它。
答案 2 :(得分:1)
根据您使用的编译器,您可以使用trim()
内在函数从字符串中删除任何前导/尾随空格,然后像往常一样处理它,即
character(len=25) :: my_string
my_string = 'AIR'
write (*,*) ':', trim(my_string), ':'
应打印:AIR:
。
编辑:
更好的是,看起来有一个len_trim()
函数在剪裁后返回字符串的长度。
答案 3 :(得分:0)
intel和Compaq Visual Fortran具有内部函数LEN_TRIM(STRING),它返回长度而没有尾随空格或空格。
如果要抑制前导空格或空格,请使用“向左调整”即ADJUSTF(STRING)
在这些FORTRAN中,我还注意到一个有用的特性:如果将一个字符串作为参数传递给函数或子例程,并且在子例程中将它声明为CHARACTER *(*),那么 在子例程中使用LEN(STRING)函数重新传入传入的实际字符串长度,而不是调用程序中声明的字符串长度。
实施例: CHARACTER * 1000 STRING
.
.
CALL SUBNAM(STRING(1:72)
SUBROUTINE SYBNAM(STRING)
CHARACTER*(*) STRING
LEN(STRING) will be 72, not 1000