[英]read with fortran binary files written with C
我知道这可能不是一个很聪明的问题,但是我有一个用C编写的代码可以生成一个二进制文件,并且我必须使用Fortran从该文件中读取数据。 我对C并不是很熟悉,但是我试图提出一个解决方案。
这是用C程序编写的文件的方式
unsigned nvarnew = 16;
std::vector<float> new_data( ncells*nvarnew, 0.0f );
sprintf(offname,"%s_pot.dat",snapname.c_str());
for( size_t i=0; i<ncells*nvarnew; ++i )
new_data[i] = bytereorder<float>(new_data[i]);
std::ofstream offs(offname,std::ios::binary);
for( size_t i=0; i<ncells; ++i )
{
offs.write( reinterpret_cast<char*>(&blocksize), sizeof(int) );
offs.write( reinterpret_cast<char*>(&new_data[nvarnew*i]), blocksize );
offs.write( reinterpret_cast<char*>(&blocksize), sizeof(int) );
}
offs.close();
在这里,我将尝试尝试使用Fortran进行阅读
subroutine read_output(filename)
implicit none
character (*),intent (in) :: filename
integer(4)::temp,temp2
real(4)::tempr
real(kind=8),allocatable,dimension(:)::dx,xgas,ygas,zgas,nH,divv
real(kind=8),allocatable,dimension(:)::force_dm_x,force_dm_y,force_dm_z
real(kind=8),allocatable,dimension(:)::force_gas_x,force_gas_y,force_gas_z
real(kind=8),allocatable,dimension(:)::force_stars_x,force_stars_y,force_stars_z
integer::Nmax,Ngas2
Nmax = 1000000
allocate(dx(Nmax),xgas(Nmax),ygas(Nmax),zgas(Nmax),nH(Nmax),divv(Nmax))
allocate(force_dm_x(Nmax),force_dm_y(Nmax),force_dm_z(Nmax))
allocate(force_gas_x(Nmax),force_gas_y(Nmax),force_gas_z(Nmax))
allocate(force_stars_x(Nmax),force_stars_y(Nmax),force_stars_z(Nmax))
open ( 19 , file = filename, form = 'unformatted',access='stream')
Ngas2=1
DO WHILE (Ngas2.lt.Nmax)
read (19,end=6) temp,dx(Ngas2),xgas(Ngas2),ygas(Ngas2),zgas(Ngas2),nH(Ngas2),divv(Ngas2),&
& force_dm_x(Ngas2),force_dm_y(Ngas2),force_dm_z(Ngas2),&
& force_gas_x(Ngas2),force_gas_y(Ngas2),force_gas_z(Ngas2),&
& force_stars_x(Ngas2),force_stars_y(Ngas2),force_stars_z(Ngas2)
read(19) temp
if(Ngas2==1) then
write(*,*) dx(Ngas2),xgas(Ngas2),ygas(Ngas2),zgas(Ngas2),nH(Ngas2),divv(Ngas2),&
& force_dm_x(Ngas2),force_dm_y(Ngas2),force_dm_z(Ngas2),&
& force_gas_x(Ngas2),force_gas_y(Ngas2),force_gas_z(Ngas2),&
& force_stars_x(Ngas2),force_stars_y(Ngas2),force_stars_z(Ngas2)
end if
Ngas2=Ngas2+1
end do
6 continue
close (19)
if( Ngas2.eq.Nmax ) then
print *, 'DATA GAS - error reading data: too many cells. Change Nmax.'
print *, 'Ngas=',Ngas2
stop
end if
Ngas2=Ngas2-1
! print *,Ngas
!print*,dx(1),xgas2(1),ygas2(1),zgas2(1),nH(1),divv(1),vortx(1),vorty(1),vortz(1),baroc(1),vortentr(1),vortrho(1),strain(1),strainpar(1),strainper(1),qp(1),qp_per(1),qp_par(1),kin(1),gforce(1),qphi(1),qphi_par(1),qphi_per(1),gx(1),gy(1),gz(1),px(1),py(1),pz(1),sx(1),sy(1),sz(1),phi(1)
end subroutine read_output
program main
implicit none
call read_output("binary_c_code.dat")
end program main
但是问题是,当我尝试打印阅读的内容时,我得到的数字实际上并没有意义。 我想问题可能出在变量的声明中。 我什至尝试将它们声明为real(kind=4)
,但是我仍然得到没有意义的数字。
new_data[i] = bytereorder<float>(new_data[i]);
我不确定这行是做什么用的(可能是您从另一端读取数据)。 除此之外,普通的C ++编写(使用旧式文件api)看起来如下:
#include <cstdio>
#include <cstdint>
#include <vector>
bool SaveVector( const char * filePath, const std::vector<float>& v )
{
bool success = false;
FILE *hFile = fopen(filePath, "wb");
if( NULL != hFile )
{
// Make sure we know it is a 4 byte signed int regarding vectors size.
int32_t vsize = static_cast<int32_t>(v.size());
if( 1 == fwrite (&vsize, sizeof(vsize), 1, hFile ) )
{
if( v.size() == fwrite( &v[0], sizeof(std::vector<float>::value_type), v.size(), hFile ) )
{
success = true;
}
}
fclose(hFile);
}
return success;
}
希望对您有所帮助。 该函数首先将向量的长度保存为4个字节的有符号整数,然后将向量的内容保存为4个字节的浮点数(在典型系统上)。
编辑 :将大小更改为带符号的4字节整数(感谢弗拉德!),修复了打字错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.