Fortran到C翻译读取未格式化的文件

时间:2016-02-10 17:42:31

标签: c types fortran

我正在努力将一小段Fortran代码翻译成C.我有一个以二进制格式编写的文件和一个读取该格式的Fortran程序。我的目标是拥有一个能够读取相同格式的C程序。我是Fortran的新手,我没有格式的原始规范。所以,这是一种逆向工程过程。

filename = 'file'
integer :: status
integer, parameter :: di=selected_int_kind(9)
integer(di) :: nn

OPEN(11,file = filename, status = 'old', action = 'read', form = 'unformatted', iostat = status)
if(status /= 0) then
   write(*,*) 'FILE ERROR: '//filename
   stop
endif
read(11) nn
CLOSE(11)

让我感到困惑的一件事是selected_int_kind()声明。到底是做什么的?什么是C中的等价物?

实际上,我第一次尝试翻译与@JohnBode的答案几乎相同,但它没有用。它读取的值完全不正确。

经过几次尝试,我找到了一个有效的解决方案,但是,我不明白为什么会这样。由于某种原因,正确的值写入第5-8个字节。所以,我可以读取两个int值(其中第二个值是正确的值),或者我可以读取long值,然后右移32位。知道为什么Fortran能够如此轻松地找到正确的值吗?

2 个答案:

答案 0 :(得分:1)

Fortran中的类型有一个KIND,因为相同类型(在您的情况下为INTEGER)可能具有不同的“风格”(有点像C中的短,长,有符号,无符号等)。这些类型是整数:例如,请参阅列表here。您的表达式selected_int_kind(9)表示:可以包含介于-1e9和1e9之间的值的最小整数类型的种类数(请参阅说明here)。

在C中,我猜signed int应该没问题,因为即使4个字节(32位)也会从-2^31增加到2^31-1,这比需要的要宽一些。

答案 1 :(得分:0)

接近1:1的翻译。

const char *filename = "file"; // or const char filename[] = "file";
long nn;

FILE *input = fopen( filename, "rb" ); // open as binary
if ( !input ) // or if ( input == NULL )
{
  fprintf( stderr, "FILE ERROR: %s\n", filename );
  exit(0);
}

if ( fread( &nn, sizeof nn, 1, input ) < 1 )
{
  fprintf( stderr, "Error while reading input\n" );
}

fclose( input );  

C与上面的“selected_int_kind”没有等价物;相反,您可以选择适当的类型来表示预期的值范围(即shortintlonglong long等。如果你需要能够代表9个十进制数字,那么普通int可能不够宽(虽然在实践中它应该是),所以你应该使用long代替。