Разбор строк в Фортран - PullRequest
       24

Разбор строк в Фортран

2 голосов
/ 06 февраля 2012

Я читаю из файла на Фортране с неопределенным числом значений с плавающей запятой в каждой строке (на данный момент в строке около 17 значений). Я хотел бы прочитать n-ное значение в каждой строке для заданной переменной с плавающей запятой. Как мне это сделать?

В C, как я написал, нужно было прочитать всю строку в строку, а затем сделать что-то вроде следующего:

for(int il = 0; il < l; il++)
{
    for(int im = -il; im <= il; im++)
        pch = strtok(NULL, "\t ");
}
for(int im = -l; im <= m; im++)
    pch = strtok(NULL, "\t ");
dval = atof(pch);

Здесь я постоянно читаю значение и выбрасываю его (таким образом, сокращая строку), пока не буду готов принять значение, которое пытаюсь прочитать.

Есть ли способ сделать это в Фортране? Есть ли лучший способ сделать это в Фортране? Проблема с моим кодом на Фортране заключается в том, что read(tline, '(f10.15)') tline1 не укорачивает tline (tline - это моя строка, содержащая всю строку, и tline1, в которую я пытаюсь ее проанализировать), поэтому я не могу использовать тот же метод, что и в моем С рутиной.

Любая помощь?

Ответы [ 2 ]

2 голосов
/ 06 февраля 2012

Проблема в том, что Fortran является системой ввода-вывода на основе записей, а C - потоковой.

Если у вас есть доступ к компилятору, совместимому с Fortran 2003 (современные версии gfortran должны работать), вы можете использовать спецификатор stream ACCESS, чтобы делать то, что вы хотите.

Пример можно найти здесь .

Конечно, если вы действительно склонны, вы можете просто использовать свою функцию C непосредственно из Fortran.Взаимодействие двух языков, как правило, простое, обычно требуется только оболочка с именем в нижнем регистре и дополнительным подчеркиванием (конечно, в зависимости от компилятора и платформы).Передача массивов или строк назад и вперед обычно не так тривиальна;но для этого примера это не понадобится.

Когда данные находятся в массиве символов, вы можете прочитать их в другую переменную, как вы делаете с подписью ADVANCE=no, т.е.

do i = 1, numberIWant
   read(tline, '(F10.15)', ADVANCE="no") tline1
end do

, где tline должен содержать ваш номер в конце цикла.

Из-за ввода-вывода на основе записей оператор READ обычно выбрасывает то, что находится после конца записи.Но ADVANCE=no говорит, что нет.

0 голосов
/ 16 февраля 2012

Если вы точно знаете, с какой позиции начинается значение, которое вы хотите, вы можете использовать дескриптор редактирования T, чтобы начать следующее чтение с этой позиции.
Скажем, например, что ширина каждого поля равна10 символов, и вы хотите прочитать пятое значение.Тогда оператор read будет выглядеть примерно так:

read(file_unit, '(t41, f10.5)') value1

Ps: Вы можете динамически создать строку формата во время выполнения с правильным номером после t, используя символьную переменную в качестве формата ииспользуйте внутреннюю запись в файл, чтобы ввести это число.
Допустим, вы хотите, чтобы значение начиналось с позиции n.Затем он будет выглядеть примерно так (я чередовал одинарные и двойные кавычки, чтобы было понятнее, где начинается и заканчивается каждая строка):

write(my_format, '(a, i0, a)') "(t", n, ', f10.5)'
read(file_unit, my_format) value1
...