Чтение типов данных Fortran в переполнении стека

У меня есть .txt, содержащий данные в типах данных Fortran. Я могу читать данные с помощью Python следующим образом.

import  fortranformat as ff

.....#more code in between.
with open(sys.argv[1]) as fh
.....#more code in between.
nodeline = ff.FortranRecordReader("(I3,I10,3E12.5)")
line = fh.readline()
data = nodeline.read(line)
#note that all the code is not provided.

Мне было интересно, есть ли способ прочитать типы данных Fortran из C ++ (без использования подстроки функции) из файла .txt.

PS. Я не предоставил полный код Python, потому что он работает должным образом, и я использую только бит, необходимый для лучшего объяснения моего вопроса.

Пример данных в файле .txt приведен ниже.

 -1         1-3.07500E+01-2.96893E+01-1.65000E+01
-1         2-3.07500E+01 2.96893E+01-1.65000E+01
-1         3-8.85000E+01 8.74393E+01-1.65000E+01
-1         4-8.85000E+01-8.74393E+01-1.65000E+01
-1         5-8.85000E+01 8.74393E+01-2.15000E+01
-1         6-8.85000E+01-8.74393E+01-2.15000E+01
-1         7-3.07500E+01 2.96893E+01-2.15000E+01
-1         8-3.07500E+01-2.96893E+01-2.15000E+01
-1         9 2.96893E+01-3.07500E+01-1.65000E+01
-1        10-2.96893E+01-3.07500E+01-1.65000E+01
-1        11-8.74393E+01-8.85000E+01-1.65000E+01

2

Решение

Используя формат, представленный в вопросе, я написал простую программу на Фортране для записи некоторых данных.

      PROGRAM TEST
WRITE(*,FMT='(I3,I10,3E12.5)') 1, 234, 5.67, 8.9, 0.123456789
END PROGRAM

Я передал вывод вышеуказанной программы в файл test.dat:

  1       234 0.56700E+01 0.89000E+01 0.12346E+00

Тогда в C ++ данные могут быть легко прочитаны с помощью std::ifstream,

#include <fstream>
#include <iostream>

int main() {
std::ifstream ifs("test.dat");

int i,j;
double d,e,f;

while (ifs >> i >> j >> d >> e >> f) {
std::cout << i << ' ' << j << ' ' << d << ' ' << e << ' ' << f << '\n';
}
}

Компиляция и запуск выходов

1 234 5.67 8.9 0.12346

Ответ на редактирование:

Если вам нужно проанализировать такой странный формат, где пробелы отсутствуют, вы можете рассмотреть возможность использования подходящего генератора синтаксического анализатора, такого как Boost.Spirit.

#include <fstream>
#include <iostream>
#include <tuple>
#include <vector>

#include <boost/fusion/adapted/std_tuple.hpp>
#include <boost/spirit/home/support/iterators/istream_iterator.hpp>
#include <boost/spirit/home/x3.hpp>

int main() {
std::ifstream input("test.dat");
input.unsetf(std::ios::skipws);
std::vector<std::tuple<int, int, double, double, double>> entries;

boost::spirit::istream_iterator first(input);
boost::spirit::istream_iterator last;

using namespace boost::spirit::x3;

bool r = phrase_parse(first, last,
*(int_ >> int_ >> double_ >> double_ >> double_),
space, entries);

if (!r || first != last) {
std::cerr << "Parsing failed at " << std::string{first, last} << '\n';
} else {
for (auto const &entry : entries) {
int i, j;
double d, e, f;
std::tie(i, j, d, e, f) = entry;
std::cout << i << ' ' << j << ' ' << d << ' ' << e << ' ' << f
<< '\n';
}
}
}
3

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector