Fortran - błąd przy czytaniu pliku

0

Kłaniam się, znów mam problem przy języku f90, który jest dla mnie zagadką.
Otóż:
Mam plik z kolumną liczb, przyjmijmy, że jest ich 100. W założeniu podczas wczytania pliku program ma sam policzyć, ile jest liczb, co zostało zaprogramowane.
Deklaruję więc tabelę jednowymiarową T i później określam jej skończoność liczbą i - która jest wynikiem liczenia pozycji.
Później wykonuję prosty zabieg w linii:

read(1,*) T

Zauważyłam, że program czyta tylko 99 wyrazów, co spowodowane jest tym, że tabela T zostaje zakodowana na 99 pozycji. Przed określeniem wymiaru więc podniosłam liczbę i o jeden (tak, by tabela T miała wymiar stu pozycji). W tym momencie niestety program dostaje samowyrzutki z komunikatem "end of file".
Problem właściwy: Program nie czyta ostatniej liczby w pliku, przy wymiarze tabeli 99 nie ma miejsca na setny wyraz (to rozumiem), a przy wymiarze tabeli 100 program się zatrzymuje z błędem "koniec pliku" (nie rozumiem, czemu).
Pytanie: Jak wprowadzić do programu ostatni wyraz w pliku? (pomijając umieszczenie konkretnej liczby w kodzie)

0

U mnie działa, tablice a2 i a wypełniają się dziesięcioma liczbami. Dodanie atrybutu iostat do instrukcji read pozwala na zignorowanie błędu eof

program numbers
implicit none
integer, dimension(:), allocatable :: a
integer, dimension(25):: a2
integer :: fh = 666
integer :: c
allocate(a(25))
a = -1
a2 = -2
open(fh, file="numbers.in", status="old", action="read")
read(fh, *, iostat=c) a
close(fh)
open(fh, file="numbers.in", status="old", action="read")
read(fh, *, iostat=c) a2
close(fh)
print *, a
print *, a2
print *, c
deallocate(a)
end program

zawartość pliku numbers.in

1
3
6
8
11
32
56
67
435
999
gfortran numbers.f90 && a.exe
           1           3           6           8          11          32          56          67         435         999          -1          -1          -1          -1          -1          -1          -1          -1          -1          -1          -1          -1          -1          -1          -1
           1           3           6           8          11          32          56          67         435         999          -2          -2          -2          -2          -2          -2          -2          -2          -2          -2          -2          -2          -2          -2          -2
        5008
gfortran --version
GNU Fortran (rev5, Built by MinGW-W64 project) 4.8.1
0

Błąd faktycznie zniknął, program to "akceptuje", natomiast wciąż nie czyta ostatniej liczby. Po prostu za ostatni wyraz tabeli podstawia zero (choć powinien czytać liczbę "-7").

0

Przepraszam za double, doklejam fragment kodu. Moja tabela ma 145 pozycji.

real, dimension(:), allocatable ::  T
integer :: n, i, k, stalapotrzebna
character :: znak

open(1, file= "Dane.txt", status="old")
i=1
      do
      call fgetc(1, znak, k)
      if(znak .eq. achar(10) )then
      i=i+1
      else 
      if(k.ne.0) then
           exit
           end if
      end if
      end do
close(1)

allocate( T(i) )

      read(1,*, iostat=stalapotrzebna) T
      close(1)

      write(*,*) "Liczba punktow obserwacyjnych: "
      write(*,*) jjjj
      write(*,*) i, T(144), T(145)

(liczba jjjj jest liczona poprawnie, kod na jej temat pominęłam)
W odpowiedzi na ekranie mam to:
http://screenshot.sh/ou0kyjm5qi9cy

0

Czytasz po raz drugi z zamkniętego pliku. Sposoby naprawy to ponowne otwarcie pliku lub niezamykanie pliku i przesunięcie aktualnego wskaźnika do pozycji początkowej 0 (fseek)

!wersja 1
close(1)
allocate( T(i) )
open(1, file= "Dane.txt", status="old")
read(1,*, iostat=stalapotrzebna) T
!wersja 2
!close(1)
allocate( T(i) )
call fseek(1, 0, 0)
read(1,*, iostat=stalapotrzebna) T
0

W morzu linijek przez przypadek nie skopiowałam też tej otwierającej plik po raz drugi (czyli - miałam ustawioną wersję nr 1 od początku). Skasowałam to i wstawiłam linijkę dotyczącą przesunięcia kursora (wersja 2), ale to wciąż nie pomogło. Wyraz ostatni jest zerowy.

      i=1
      do
      call fgetc(1, znak, k)
      if(znak .eq. achar(10) )then
      i=i+1
      else 
      if(k.ne.0) then
           exit
           end if
      end if
      end do
      allocate( T(i) )     
      call fseek(1, 0, 0)
      k=1
      read(1,*, iostat=stalapotrzebna) T
      close(1)

http://screenshot.sh/m3AcrkAd1ujtA

0

(tak nad i=1 wciąż jest otwieranie pliku przez open)

0

nie wiem, co się dzieje u ciebie, tutaj program bezproblemowo odczytuje 6 liczb z wejścia https://ideone.com/Qu9PEZ

0

Nie znam fortrana, ale czy wasze pliki mają identyczną budowę? Tzn. czy po ostatniej liczbie jest w pliku znak nowej linii?

0

Faktycznie, u mnie w pliku wejściowym po ostatniej liczbie nie było znaku nowej linii (tylko znak końca pliku). Po dostawieniu jednej pustej linii na końcu pliku program już czyta poprawnie cały plik.
Tylko pytanie, czy jet sposób, by to obejść? Nie wiem, w jakiej formie będą później ludzie wstawiać pliki wejściowe, a nie chcę na nich wywierać przymusu, żeby każdy plik danych kończył się pustą linią.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0