2013-02-27 2 views
0

Я пытаюсь использовать fortran для записи файла с разделителями-запятыми для импорта в другой коммерческий пакет. Проблема в том, что у меня есть неизвестное количество столбцов данных. Мой выход должен выглядеть следующим образом:Оператор формата с неизвестными столбцами

a_string,a_float,a_different_float,float_array_elem1,float_array_elem2,...,float_array_elemn 

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

L1080,546876.23,4325678.21,300.2,150.125,...,0.125 
L1090,563245.1,2356345.21,27.1245,...,0.00983 

У меня есть три вопроса. Во-первых, я бы предпочел, чтобы элементы были плотно сгруппированы (переменная ширина столбца), два, я не знаю, как определить переменное число элементов массива в инструкции формата, и три элемента массива могут охватывать большой диапазон - возможно, на 12 порядков. Следующий код концептуально делает то, что я хочу, но переменная «п» и отсутствие столбца ширины определения выдает ошибку (конечно):

WRITE(50,900) linenames(ii),loc(ii,1:2),recon(ii,1:n) 
900 FORMAT(A,',',F,',',F,n(',',F)) 

(следует отметить, что п фиксируется время выполнения .) Оператор записи делает то, что я хочу, когда я делаю WRITE (50, *), за исключением того, что он ограничен шириной.

Я думаю, что эта нить почти ответила на мой вопрос, но я довольно смутился: SO. Прямо сейчас у меня есть сценарий оболочки с awk, который исправляет проблему, но это решение ... неэлегантное. Я мог бы сделать некоторые манипуляции, чтобы сделать вывод строкой, а затем просто написать ее, но я бы предпочел избежать этой опции, если это вообще возможно.

Я делаю это в Fortran 90, но мне нравится пытаться сохранить мой код как можно более обратной совместимости.

+0

Я также должен отметить, что причина, по которой мне нужны жесткие столбцы, двояка: одна, то есть желаемый вход для следующей программы и два размера. В результирующем выходном файле может быть несколько миллионов строк со многими десятками столбцов. Пространства имеют значение! Спасибо –

ответ

1

Формат, близкий к тому, что вы хотите, - f0.3, это не даст пробелов и фиксированного количества десятичных знаков. Я думаю, что если вы хотите также уничтожить завершающие нули, вам нужно будет немного поработать.

«n» в вашем заявлении на запись может быть больше, чем количество значений данных, поэтому один (старая школа) подход заключается в том, чтобы разместить там большое число, например 100000. Современный fortran имеет некоторый синтаксис для указания неопределенного повторения , я уверен, что кто-то предложит это.

---- редактировать неограниченное повторение, как вы могли бы угадать asterisk..and является evideltly «новый» в F2008

1

Для того, чтобы убедиться, что нет места происходит между записями в строке , вы можете написать их отдельно в переменных символов, а затем распечатать их с помощью функции adjustl() в Fortran:

program csv 
    implicit none 

    integer, parameter :: dp = kind(1.0d0) 
    integer, parameter :: nn = 3 
    real(dp), parameter :: floatarray(nn) = [ -1.0_dp, -2.0_dp, -3.0_dp ] 
    integer :: ii 
    character(30) :: buffer(nn+2), myformat 

    ! Create format string with appropriate number of fields. 
    write(myformat, "(A,I0,A)") "(A,", nn + 2, "(',',A))" 
    ! You should execute the following lines in a loop for every line you want to output 
    write(buffer(1), "(F20.2)") 1.0_dp ! a_float 
    write(buffer(2), "(F20.2)") 2.0_dp ! a_different_float 
    do ii = 1, nn 
    write(buffer(2+ii), "(F20.3)") floatarray(ii) 
    end do 
    write(*, myformat) "a_string", (trim(adjustl(buffer(ii))), ii = 1, nn + 2) 

end program csv 

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

+0

один раз здесь вы можете с легкостью перейти еще на один шаг и разделить конечные нули (предположительно написать простую функцию, подобную тому, что обрезает пробел или 0.) – agentp

Смежные вопросы