如何用fortran 在文本文件最后写入内容

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何用fortran 在文本文件最后写入内容相关的知识,希望对你有一定的参考价值。

    如果你的文本文件每一行都是一样的长度。那么你可以试试用 “有格式文件直接读写方式” 打开文件。

    如果你的文本文件每一行长度不同。则有点难办。如果你用的 windows 下的 Compaq Visual Fortran ,Digital Visual Fortran ,Intel Visual Fortran 这系列的编译器。你可以在 Open 时指定 ACCESS = 'APPEND'  。则表示打开文件后,直接在文件末端读写。但这样做的结果是:你的代码以后就只能在这些编译器上使用,如果换到其他编译器,则无法正常编译链接。

    如果每一行长度不同,你又想保持代码的兼容性。你可以把原文件全部读出来,写入新文件,然后在新文件里继续写入。最后删掉原文件。

参考技术A WRITE(1111,"(D8.2,1x,D8.2,1x,D8.2,1xD8.2)") NODE_CORD(I,1),NODE_CORD(I,2),NODE_CORD(I,3),NODE_ALPHA(I)
其中,D8.2表示以8个字符宽度来输出指数类型浮点数,小数部分占2个字符宽度。1x表示指针向后移动一个空格。
注意输出的必须是浮点数,如果你前三个数是整型数,你必须先将其转化为浮点数在输出。real(NODE_CORD(l,1)).

如何用 c 或 c++ 读取 FORTRAN 二进制文件?

【中文标题】如何用 c 或 c++ 读取 FORTRAN 二进制文件?【英文标题】:How to read FORTRAN binary file with c or c++? 【发布时间】:2016-10-21 15:52:29 【问题描述】:

我有 FORTRAN 77 二进制文件(在 Sun Sparc 机器上创建,大端)。我想在我的小端机器上阅读它。我遇到过这个

http://paulbourke.net/dataformats/reading/

Paul 为 C 或 C++ 编写了这些宏,但我不明白它们的真正作用。

#define SWAP_2(x) ( (((x) & 0xff) << 8) | ((unsigned short)(x) >> 8) )
#define SWAP_4(x) ( ((x) << 24) | (((x) << 8) & 0x00ff0000) | \
         (((x) >> 8) & 0x0000ff00) | ((x) >> 24) )
#define FIX_SHORT(x) (*(unsigned short *)&(x) = SWAP_2(*(unsigned short *)&(x)))
#define FIX_LONG(x) (*(unsigned *)&(x) = SWAP_4(*(unsigned *)&(x)))
#define FIX_FLOAT(x) FIX_LONG(x)

我知道文件的每条记录都包含包含

x,y,z,t,d,i

i 是整数*2,所有其他变量都是实数*4。 前 512 字节 hexdump

0000000 0000 1800 0000 0000 0000 0000 0000 0000
0000010 0000 0000 0000 0000 ffff ffff 0000 1800
0000020 0000 1800 003f 0000 0000 0000 233c 0ad7
0000030 0000 0000 233c 0ad7 0000 0100 0000 1800
0000040 0000 1800 803f 0000 0000 0000 233c 0ad7
0000050 0000 0000 233c 0ad7 0000 0100 0000 1800
0000060 0000 1800 c03f 0000 0000 0000 233c 0ad7
0000070 0000 0000 233c 0ad7 0000 0100 0000 1800
0000080 0000 1800 0040 0000 0000 0000 233c 0ad7
0000090 0000 0000 233c 0ad7 0000 0100 0000 1800
00000a0 0000 1800 2040 0000 0000 0000 233c 0ad7
00000b0 0000 0000 233c 0ad7 0000 0100 0000 1800
00000c0 0000 1800 4040 0000 0000 0000 233c 0ad7
00000d0 0000 0000 233c 0ad7 0000 0100 0000 1800
00000e0 0000 1800 6040 0000 0000 0000 233c 0ad7
00000f0 0000 0000 233c 0ad7 0000 0100 0000 1800
0000100 0000 1800 8040 0000 0000 0000 233c 0ad7
0000110 0000 0000 233c 0ad7 0000 0100 0000 1800
0000120 0000 1800 9040 0000 0000 0000 233c 0ad7
0000130 0000 0000 233c 0ad7 0000 0100 0000 1800
0000140 0000 1800 a040 0000 0000 0000 233c 0ad7
0000150 0000 0000 233c 0ad7 0000 0100 0000 1800
0000160 0000 1800 b040 0000 0000 0000 233c 0ad7
0000170 0000 0000 233c 0ad7 0000 0100 0000 1800
0000180 0000 1800 c040 0000 0000 0000 233c 0ad7
0000190 0000 0000 233c 0ad7 0000 0100 0000 1800
00001a0 0000 1800 d040 0000 0000 0000 233c 0ad7
00001b0 0000 0000 233c 0ad7 0000 0100 0000 1800
00001c0 0000 1800 e040 0000 0000 0000 233c 0ad7
00001d0 0000 0000 233c 0ad7 0000 0100 0000 1800
00001e0 0000 1800 f040 0000 0000 0000 233c 0ad7
00001f0 0000 0000 233c 0ad7 0000 0100 0000 1800
0000200

我读取文件的代码

#include <endian.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

int main() 

    FILE *file;
    char *buffer;
    char *rec;
    long fileLen;

    file = fopen("rec.in", "rb");


    fseek(file, 0, SEEK_END);
    fileLen=ftell(file);
    fseek(file, 0, SEEK_SET);

    buffer=(char *)malloc(fileLen+1);

    fread(buffer, fileLen, 1, file);
    fclose(file);
    free(buffer);

char *curr = buffer;
char *end = buffer + fileLen;

constexpr int LINE_SIZE = sizeof(float)*5 + sizeof(uint16_t); //based upon your "x,y,z,t,d,i" description

while(curr < end) 
    uint32_t temp = be32toh(*reinterpret_cast<uint32_t*>(*curr));
    float x = *reinterpret_cast<float*>(&temp);

    temp = be32toh(*reinterpret_cast<uint32_t*>(*(curr+sizeof(float))));
    float y = *reinterpret_cast<float*>(&temp);

    temp = be32toh(*reinterpret_cast<uint32_t*>(*(curr+2*sizeof(float))));
    float z = *reinterpret_cast<float*>(&temp);

    temp = be32toh(*reinterpret_cast<uint32_t*>(*(curr+3*sizeof(float))));
    float t = *reinterpret_cast<float*>(&temp);

    temp = be32toh(*reinterpret_cast<uint32_t*>(*(curr+4*sizeof(float))));
    float d = *reinterpret_cast<float*>(&temp);

    uint16_t i = be16toh(*reinterpret_cast<uint16_t*>(*(curr+5*sizeof(float))));

    curr += LINE_SIZE;




我有两个错误 r.cc: 在函数'int main()'中:

r.cc:29:1: error: ‘constexpr’ was not declared in this scope
 constexpr int LINE_SIZE = sizeof(float)*5 + sizeof(uint16_t); //based upon your "x,y,z,t,d,i" description
 ^
r.cc:49:13: error: ‘LINE_SIZE’ was not declared in this scope
     curr += LINE_SIZE;

【问题讨论】:

这些宏很危险,并且使用了一些过时的技术,例如依赖具有 16 位的 short C 和 C++ 是不同的语言!您的代码看起来像 C,选择 一种 语言! 这就是为什么人类可读的格式更受欢迎的原因。 您的二进制文件在您必须跳过的数据之前和之后也有 64 位大端记录长度。 FWIW,英特尔 Fortran 支持使用其 CONVERT="BIG_ENDIAN" 选项读取此类文件。 @SteveLionel 好的,谢谢,稍后再试。 【参考方案1】:

如果您在 linux 机器上读取文件,endian.h 标头(文档here)中为此目的提供了一些库函数。要将 16 位整数转换为主机顺序(在您的情况下为小端序):

uint16_t hostInteger = be16toh(bigEndianIntegerFromFile);

对于浮点数,您可以做类似的事情,但需要重新解释:

float hostFloat = reinterpret_cast<float>(be32toh(reinterpret_cast<uint32_t>(bigEndianFloatFromFile)));

或者,如果您一开始将其读作unsigned int,则不需要内部的reinterpret_cast

float hostFloat = reinterpret_cast<float>(be32toh(bigEndianUint32FromFile));

更新:给定您的代码,您可以通过在 fclosefree 调用之间插入来读取文件:

char *curr = buffer;
char *end = buffer + fileLen;

constexpr int LINE_SIZE = sizeof(float)*5 + sizeof(uint16_t); //based upon your "x,y,z,t,d,i" description

while(curr < end) 
    uint32_t temp = be32toh(*reinterpret_cast<uint32_t*>(*curr));
    float x = *reinterpret_cast<float*>(&temp);

    temp = be32toh(*reinterpret_cast<uint32_t*>(*(curr+sizeof(float))));
    float y = *reinterpret_cast<float*>(&temp);

    temp = be32toh(*reinterpret_cast<uint32_t*>(*(curr+2*sizeof(float))));
    float z = *reinterpret_cast<float*>(&temp);

    temp = be32toh(*reinterpret_cast<uint32_t*>(*(curr+3*sizeof(float))));
    float t = *reinterpret_cast<float*>(&temp);

    temp = be32toh(*reinterpret_cast<uint32_t*>(*(curr+4*sizeof(float))));
    float d = *reinterpret_cast<float*>(&temp);

    uint16_t i = be16toh(*reinterpret_cast<uint16_t*>(*(curr+5*sizeof(float))));

    curr += LINE_SIZE;

    ...
    //do something with these values
    ...

【讨论】:

当然,他没有使用 C++ 流。如果你愿意,你可以称它为 C 而不是 C++,但我认为这不会使他的问题无效。他很可能在其他地方有更多的 C++ 代码,我不打算评判。 @MikiBelavista - 我对代码进行了一些编辑,您必须对指针而不是值进行 reinterpret_cast。但是,第一个编译错误只是缺少括号,您至少应该尝试自己修复它们! @Smeeheey 感谢帮助,我稍微改了一下,还是有两个错误。 constexpr更改为const

以上是关于如何用fortran 在文本文件最后写入内容的主要内容,如果未能解决你的问题,请参考以下文章

请问如何用matlab创建TXT文本文档啊?

如何用JavaScript打开WORD写入文本

Python 文件操作

如何用python将变量及其值写入文本文件?

如何用Java或C语言解析二进制文件为文本文件?

在linux中给一个文本文件写内容的方法(三种)