Неправильные результаты при чтении файла txt в выделяемый массив с использованием Fortran 90

Я пытаюсь решить проблемы, связанные с сохранением значений, когда я использую de/allocate в коде, показанном ниже (fortran), создавая массив копий, но проблема не устранена. Я уже видел ссылки по теме:

Массив Fortran автоматически увеличивается при добавлении значения

Как получить ранее неизвестный массив в качестве вывода функции на Фортране

Было бы легко и не имеет смысла (для целей этого кода), если бы я знал размерность массива (ввод из txt-файла).

Возможно, я делаю некоторые ошибки (одна из них очевидна: минутный размер против ожидаемого общего размера). Буду признателен, если кто-то их укажет. Несмотря на это, я не могу понять, как создание массива копий может решить проблему, потому что мне нужно де/распределить как временные, так и основные переменные.

Итак, можно ли прочитать txt без информации о «переменном измерении», используя перераспределение (де/распределение)?

Это код (с использованием f90):

program prueba
    implicit none
    integer, dimension(:), allocatable :: minuto, temp
    integer :: iounit, ierr
    integer :: i = 1
    integer :: n = 1

    open(newunit = iounit, file = 'datos.txt')
    read(iounit,*)

    allocate(minuto(n), temp(n))
    minuto = 0; temp = 0
    !-------------------------------------------

    do
        read(unit = iounit, fmt = '(i2)',iostat = ierr) temp(i)
        if (ierr/=0) exit

            if (mod(size(temp,1),5)==0) then
                deallocate(minuto)
                allocate(minuto(i))
                minuto((i-4):i) = temp((i-4):i)
            end if
        i = i+1
        deallocate(temp)
        allocate(temp(i))
    end do

    close(iounit)

print*,minuto

end program prueba

(Я знаю лучшие способы достижения той же цели, это просто упражнение для углубления)

Я использую этот пример данных (из txt):

min
 5
10
15
20
25
30
35
40
45
50
55
 0

Вот результат:

-2144186072 1 -2144186072 1 25 0 35 40 45 50

Пожалуйста, используйте тег fortran для всех вопросов по Fortran.

Vladimir F Героям слава 25.12.2020 10:44

Обязательно всегда включайте все проверки компилятора. gfortran -g -Wall -fcheck=all. Valgrid или sanitizations -fsanitize=address,undefined также полезны, чтобы выяснить, откуда берутся неинициализированные значения.

Vladimir F Героям слава 25.12.2020 11:07

В minuto((i-4):i) вы не присваиваете значения всем значениям этого массива. Как видите, только последние пять значений соответствуют ожиданиям.

francescalus 25.12.2020 14:02

Франческал прав. вы можете использовать move_alloc на minuto, затем выделить его большего размера и повторно скопировать в него сохраненные значения (сохраненные с помощью move_alloc).

jack 25.12.2020 14:12

@VladimirF Спасибо, я не знал некоторых из этих флагов. Это будет полезно.

user 25.12.2020 17:16
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
123
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В процессе перераспределения вы освобождаете minuto и не сохраняете его старые данные.

Это пример программы, которая может сработать для вас

program prueba
  implicit none

  integer, allocatable :: minuto(:)
  integer, parameter   :: n = 2
  integer              :: iounit, ierr, temp(n), i

  open (newunit = iounit, file = 'datos.txt')
  read (iounit, *)

  ! init minuto. needed for move_alloc in first call
  allocate (minuto(0))

  i = 1
  do
    read (unit = iounit, fmt = '(i2)', iostat = ierr) temp(i)

    ! exit loop. still save temp(1:i-1)
    if (ierr /= 0) then
      if (i > 1) call save_temp(i-1)
      exit
    end if

    ! save all of temp
    if (i == n) call save_temp(n)

    i = mod(i, n) +1
  end do

  close (iounit)

  print *, minuto

contains
  subroutine save_temp(n_temp)
    !! append temp(1:n_temp) to minuto

    integer, intent(in) :: n_temp

    integer, allocatable :: temp_reloc(:)

    ! save old data from minuto into temp_reloc
    call move_alloc(minuto, temp_reloc)

    allocate (minuto(size(temp_reloc) + n_temp))

    ! init first part of minuto by its old data
    minuto(:size(temp_reloc))   = temp_reloc

    ! append temp's data
    minuto(size(temp_reloc)+1:) = temp(1:n_temp)
  end subroutine
end program

Выход

$  gfortran -g3 -Wall -fcheck=all a.f90 && ./a.out
           5          10          15          20          25          30          35          40          45          50          55           0

Я хотел бы отметить, что move_alloc() - это Fortran 2003, а не Fortran 90. В наши дни это не имеет большого значения, но @Isaac, похоже, просил Fortran 90, в частности. В противном случае все ссылки, которые он получил ранее (также в предыдущем вопросе), также применимы.

Vladimir F Героям слава 25.12.2020 17:28

Другие вопросы по теме