Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Fortran > [General] файлы и массивы


Автор: f999t1 4.10.2008, 21:41
как реализовать следующее действие:
нужно из текстового файла, в котором записан набор чисел-массив MxN
перегнать его в массив a(m,n) 

Автор: popovda 7.10.2008, 15:20
Очень просто. Если данные записаны по строкам, то так:
M -  число строк, N-столбцов. Допустим, данные - вещественные числа, разделенные пробелами 

open(1111,file='имя_файла.txt')
do i = 1,M
     read(1111,*) a(i,:)
end do;

close(1111);

Добавлено @ 15:23
Или можно так:

real(8) :: a(m,n), tmp(n,m)

.........
read(1111,*) tmp;

a = transpose(tmp)

Пользуясь тем, что в Фортране массивы расположены ПО СТОЛБЦАМ, а не по строкам.

Автор: Иванофф 7.10.2008, 23:39
тов.popovda с педагогической точки зрения с такими вопросами нужно посылать как минимум читать учебник. любой учебник по фортрану начиная с 70-х годов содержит подобную информацию.

Автор: popovda 9.10.2008, 17:05
Ну а на кой тогда форумы нужны, тов. Иванофф? Я сам когда ковыряться не хочу - не брезгую ими.

Автор: Иванофф 10.10.2008, 01:57
на форуме должен быть некий уровень вопросов, ответы на которые не достаточно очевидны и требуют специфических знаний. пересказ учебников начального уровня не способствует развитию форума, тем более такого "посещаемого и динамичного".

Автор: Cr@$h 18.1.2009, 18:19
Да ну бросьте вы. Посмотрите на самые развитые форумы по языкам на Винграде. Там везде есть подфорумы "Для новичков". Когда-нибудь подобные темы пойдут именно в подобный форум, лишь бы развитие состоялось.

А я то по другому поводу..

Цитата(popovda @  7.10.2008,  16:20 Найти цитируемый пост)

Код

real(8) :: a(m,n), tmp(n,m)

.........
read(1111,*) tmp;

a = transpose(tmp)

Мне кажется запись в памяти и чтение из файла вещи не одни и те же. Да, пусть он в память пишет по столбцам, но матрица остаётся матрицей. И если читать её из файла, то всё должно быть нормально:
Код

real(8) :: a(m,n)

.........
read(1111,*) a(m,n)

Нет? Не могу проверить сейчас :-(

Автор: Фантом 18.1.2009, 18:44
Есть более интересный вопрос... smile Зачем возиться с циклами, транспонированиями и т.п., если можно сделать так:
Код

  real, dimension(M,N) :: a
  open(11,file="data.dat")
  read (11,*) a
  close(11)


Все. Разработчки стандарта Fortran90 уже обо всем подумали.  smile   




Автор: Cr@$h 18.1.2009, 19:15
 smile я же это и предложил, но не имею возможности проверить это сейчас.

Автор: sfes 6.4.2009, 17:23
Цитата

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

Код

real, dimension(M,N) :: a
open(11,file="data.dat")
read (11,*) a
close(11)


Все. Разработчки стандарта Fortran90 уже обо всем подумали.  smile   

А как сделать то же самое, но только если одна размерность не известна?
Т.е. если количество строк в матрице переменное?

Автор: FatalError 7.4.2009, 11:28
Задача нехитрая, еще на уровне Фортрана77 были нормальные средства для ее решения. Вот я в пределах Ф77 и объясню, честно говоря, сам не знаю, как это сделать более современными средствами языка.

Если количество строк заранее не определено, придется, во-первых, заранее объявить массив заведомо больших размеров, чтобы вся матрица гарантированно влезла. Во-вторых, запустить цикл чтения с заполнением объявленного нами массива, считая, что мы должны заполнить его целиком. По ходу чтения программа прочитает всю матрицу и неизбежно налетит на конец файла. Если мы заранее не примем никаких мер, тут наша программа и вылетит с ошибкой. Чтобы этого не произошло, в Ф77 можно использовать такой вариант: указать параметр ERR при записи оператора READ. Запись примерно такая:

READ (UNIT=12, FMT=*, ERR=666) тут - элементы матрицы, которые надо прочитать

При обнаружении ошибки ввода-вывода программа должна перейти на метку 666, которую, по логике вещей, мы должны поставить сразу за пределами описанного выше цикла чтения матрицы. Это не красиво, завершение работы цикла безусловным переходом за его пределы не способствует оптимизации, но это работает. Да и в циклах чтения-записи и оптимизировать-то нечего. Вообще-то, кажется, последние стандарты Фортрана запрещают выход из цикла по безусловному переходу, так что, по логике вещей, должен быть и более кошерный способ сделать это же самое. Но я его не знаю  smile 

Автор: FCM 9.4.2009, 13:22
Цитата(sfes @  6.4.2009,  17:23 Найти цитируемый пост)
А как сделать то же самое, но только если одна размерность не известна?
Т.е. если количество строк в матрице переменное?


Если матрица записана по строкам, после каждой из которых следует перевод строки (т.е. одна строка = одна запись) и число элементов в строке известно, то можно объявить allocatable 2-мерный массив, затем сделать холостой прогон цикла типа DO WHILE( .NOT.EOF(UNIT_NUMBER)), в котором вычислить количество строк, затем сделать REWIND,  разместить массив и считать в него матрицу.

Автор: FatalError 9.4.2009, 15:06
FCM 
Да, оказывается, есть такая встроенная логическая функция - EOF. А я и не знал! Вариант вполне годится. 

З.Ы.: Пардон, данная функция не встроенная, а имеет характер Intrinsic procedure Extensions. Типа, нестандартная и не везде работает.

Автор: popovda 9.4.2009, 22:03
Во всех случаях я поступаю одинаково, именно так вывожу матрицы. И вот почему - вывод данных в файл в стандартной последовательности (именно так, как он лежит в памяти), как предложил один из форумчан удобна, если вводить потом куда-нибудь вы их будите то же по столбцам, а не по строкам. Но, экселю, C/C++ и самому человеку удобнее восприятие матриц по строкам. Поэтому я так и написал. Мало ли куда пойдет этот файл потомsmile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)