【问题标题】:Output unformatted C++ similar to FORTRAN输出类似于 FORTRAN 的未格式化 C++
【发布时间】:2023-05-24 22:38:01
【问题描述】:

我希望将一些 FORTRAN 代码转换为 C++。 我在未格式化的输出方面遇到了一些问题。

在 FORTRAN 中我有一些代码如下

program main
integer*4 :: one
one = 1
open(unit = temp, file = "temp.dat", status = 'replace', form='unformatted')
WRITE(temp) one, one
end

这段代码的输出最终是

0x0800 0000 0100 0000 0100 0000 0800 0000 
0x0a

所以对我来说,输出似乎有点奇怪。我一直在玩它,我认为 0x08 是要写入的变量的大小,两个 0x00000001 是要写入的两个四字节的,而 0x00000008 可能是关闭大小的缓冲区(我不知道为什么当打开缓冲区是单个字节时这将是 4 个字节)。 0x00000a 似乎是一个 EOF 字符。

当我尝试用 C++ 模拟输出时,我会这样做

int main(){
    long one = 1;
    std::ofstream outFile;
    outFile.open("temp.dat", std::ofstream::out)
    outFile << one << one;
    outFile.close()
}

这不起作用,因为它试图将字符串写入 1 而不是二进制,所以我尝试了:

int main(){
    long one = 1;
    std::ofstream outFile;
    outFile.open("temp.dat", std::ofstream::out) 
    outFile.write((char*) one, sizeof(one));  //Line a
    outFile.write((char*) one, sizeof(one));
    outFile.close()
}

希望通过将其转换为 char 来输出直接二进制文件。 不幸的是,这在 a 线上有一个 SigSev 故障。我不太清楚为什么。

这样的方法是一个好方法,还是我应该尝试不同的方向?

【问题讨论】:

  • 确保openbinary mode中的文件。
  • FORTRAN 在每次写入之前和之后写入记录的大小。所以你的猜测是正确的。
  • 试试outFile.write(reinterpret_cast&lt;const char*&gt;(&amp;one), sizeof one);
  • Fortran 程序的这样的输出是不可互换的:这些数据的写入方式可能因编译器和编译器版本而异,甚至因要写入的记录的属性而异。根据您想要对输出执行的操作,您最好不要尝试模仿您的 Fortran 编译器正在执行的操作。

标签: c++ fortran output ofstream


【解决方案1】:

所以从 chtz 窃取,我找到了一种方法来匹配两个输出。不知道这样是不是最有效率。

int main(){
    int one = 1;
    int sizeOf = 2*sizeof(one);
    std::ofstream outFile;
    outFile.open("temp.dat", std::ofstream::out) 
    outFile.write(reinterpret_cast<const char*>(&sizeOf),sizeof(sizeOf)); 
    outFile.write(reinterpret_cast<const char*>(&one),sizeof(one));
    outFile.write(reinterpret_cast<const char*>(&one),sizeof(one));
    outFile.write(reinterpret_cast<const char*>(&sizeOf),sizeof(sizeOf));  

    outFile.close()
}

【讨论】: