Ошибка чтения данных в матрицу 3x3 в Fortran [duplicate]

Я предпочитаю XPath для таких вещей:

In [1]: from lxml.etree import parse

In [2]: tree = parse('/tmp/database.xml')

In [3]: for post in tree.xpath('/Database/BlogPost'):
   ...:     print 'Author:', post.xpath('Author')[0].text
   ...:     print 'Content:', post.xpath('Content')[0].text
   ...: 
Author: Last Name, Name
Content: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas dictum dictum vehicula.
Author: Last Name, Name
Content: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas dictum dictum vehicula.
Author: Last Name, Name
Content: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas dictum dictum vehicula.

Я не уверен, что он отличается от обработки больших файлов. Замечания об этом будут оценены.

Выполняйте свой путь,

for event, element in etree.iterparse(path_to_file, tag="BlogPost"):
     for info in element.iter():
         if info.tag in ('Author', 'Content'):
             print info.tag, ':', info.text

1
задан Vladimir F 16 October 2016 в 08:18
поделиться

2 ответа

Да, ваш формат не подходит для данных, которые вы показываете. Лучше должно быть так read(99,'(6(E11.4,X))') myData(i,:).

Тем не менее, я не уверен, что вам действительно нужно использовать формат при чтении вообще.

Ниже приведен пример, близкий к тому, что вы пытаетесь сделать, и он работает ботом с форматом и без него.

program readdata
  implicit none
  real, allocatable :: myData(:,:)
  real              :: myLine
  integer           :: i, j, myRow, myColumn
  character(len=30) :: myFileName
  character(len=30) :: myFormat

  myFileName='data.dat'

  open(99, file=myFileName)
  write(*,*)'open data file'
  read(99, *) myRow
  read(99, *) myColumn

  allocate(myData(myRow,myColumn))

  do i=1,myRow
    read(99,*) myData(i,:)
    !read(99,'(6(E11.4,X))') myData(i,:)
    print*, myData(i,:)
  enddo

  close(99)

end program readdata

Чтобы проверить, я предположил, что у вас всегда есть строки и столбцы в файле, так как мои тестовые данные следуют.

2
6
2.9900E-35  2.8000E-35  2.6300E-35  2.4600E-35  2.3100E-35  2.1600E-35
2.9900E-35  2.8000E-35  2.6300E-35  2.4600E-35  2.3100E-35  2.1600E-35

Если вам действительно интересно прочитать ваши файлы в формате, и если количество столбцов не является постоянным, вам может понадобиться формат в зависимости от переменной, см. связанные обсуждения здесь .

1
ответ дан Community 16 August 2018 в 02:48
поделиться
  • 1
    Спасибо за ответ! Мне нужно будет обновить свои знания о форматах :) – user2346329 17 October 2016 в 12:09

Хотя нет прямой команды для подсчета количества элементов в строке, мы можем подсчитать количество периодов или (E | e | D | d) с помощью команды scan . Например,

program main
    implicit none
    character(100) str
    integer n  
    read( *, "(a)" ) str

    call countreal( str, n )
    print *, "number of items = ", n
contains

subroutine countreal( str, num )
    implicit none
    character(*), intent(in)  :: str
    integer,      intent(out) :: num
    integer pos, offset

    num = 0
    pos = 0
    do
        offset = scan( str( pos + 1 : ), "." )        !! (1) search for periods
        !! offset = scan( str( pos + 1 : ), "EeDd" )  !! (2) search for (E|e|D|d)

        if ( offset > 0 ) then
            pos = pos + offset
            num = num + 1
            print *, "pos=", pos, "num=", num   !! just for check
        else
            return
        endif
    enddo
endsubroutine
end

Обратите внимание, что шаблон (1) работает только тогда, когда все элементы имеют периоды, а шаблон (2) работает только тогда, когда все элементы имеют показатели:

# When compiled with (1)

$ echo "2.9900  2.8000E-35  2.6300D-35  2.46  2.31" | ./a.out
 pos=           2 num=           1
 pos=          10 num=           2
 pos=          22 num=           3
 pos=          34 num=           4
 pos=          40 num=           5
 number of items =            5

# When compiled with (2)

$ echo "2.9900E-35  2.8000D-35  2.6300e-35  2.4600d-35" | ./a.out
 pos=           7 num=           1
 pos=          19 num=           2
 pos=          31 num=           3
 pos=          43 num=           4
 number of items =            4

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

1
ответ дан roygvib 16 August 2018 в 02:48
поделиться
  • 1
    Спасибо за подпрограмму! Раньше не использовалось сканирование, но оно кажется самым простым решением. – user2346329 18 October 2016 в 09:13
Другие вопросы по тегам:

Похожие вопросы: