Προς το περιεχόμενο

Kremala se Fortran


tasosos

Προτεινόμενες αναρτήσεις

Δημοσ.

Αν έχω καταλάβει προσπαθείς να εμφανίσεις τη λέξη στην οθόνη για να βεβαιωθείς ότι τη διάβασε σωστά.Το μόνο φανερό λάθος που βλέπω, είναι ότι προσπαθείς να διαβάσεις και να γράψεις στο ίδιο αρχείο

>OPEN([color=blue]10[/color],FILE='kremala.txt')
READ([color=blue]10[/color],*) leksi
WRITE([color=red]10[/color],*) "H leksh einai :", leksi

Για δοκίμασε κάτι σαν WRITE(*,*) "H leksh einai :", leksi

Από κει και πέρα: Η Fortran είναι αρκετά ιδιότροπη με τον τρόπο χειρισμού αρχείων ανάλογα με την έκδοση και το λειτουργικό, πολύ περισσότερο στα αλφαριθμητικά.

Γράψε μας αν θές την έκδοση που χρησιμοποιείς (ελπίζω νάναι τουλάχιστον η Visual Fortran της Sun) και τα μηνύματα λάθους.

Τέλος: Χρησιμοποιείς μονά quotes (στο όνομα αρχείου) και παρακάτω διπλά (Στο μήνυμα "H leksh einai :"). Τα περνάει και τα δύο ο Compiler?

 

PS. Το ξέρετε το ανέκδοτο: "...Τι μου θύμησες τώρα.."

Δημοσ.

loubas

Otan lew "den douleuei" ennow oti kanei compile alla meta enw trexw thn askisi

den emfanizei kanena apotelesma.

 

gerontas

Διόρθωσα το λάθος με το αρχείο στο write και τώρα εμφανιζει μια λέξη, την πρώτη λέξη που υπάρχει στο αρχείο.

Τώρα όμως την λέξη που διαβάζει πού πάει και την γράφει??

Ο compiler που χρισιμοποιώ είναι ένας g77 για windows, συγκεκριμένα http://www.geocities.com/Athens/Olympus/5564

Με τα quotes δεν υπάρχει κανένα πρόβλημα μέχρι στιγμής τουλάχιστον.

Τώρα....για να διαβάζει κάθε φορά διαφορετική λέξη(ίσως με συνάρτηση ...κατι σαν την rand στην c??) αλλά και να μπορεί να προσθέτει και να αφαιρεί λέξεις από το αρχείο πώς θα γίνει???

Δημοσ.
...τώρα εμφανιζει μια λέξη, την πρώτη λέξη που υπάρχει στο αρχείο.
Είναι λογικό αφού ...αυτό του ζητήσαμε να κάνει: Να διαβάσει μία μόνο φορά. Μια και μιλάς στη συνέχεια για C, το ανάλογο θα ήταν
>     in = fopen("kremala.txt", "rt");
    fscanf(in,"%s",s);
    puts(s);

  ενώ όπως καταλαβαίνεις θέλει κάτι σαν:

  in = fopen("kremala.txt", "rt");
  while (!feof(in)){
    fscanf(in,"%s",s);
    puts(s);
  }

Πώς γίνεται αυτό στη FORTRAN? Δυστυχώς με ποικίλους τρόπους. Δες άν η υλοποίηση που δουλεύεις -δεν την ξέρω δυστυχώς- υποστηρίζει EOF και WHILE, ώστε να γράψεις κάποιο LOOP, άν όχι, είναι σχεδόν standard μια παράμετρος στην READ, κάπως έτσι:

>      DO
        READ(10,*,END=99) leksi
        WRITE(*,*) 'H leksh einai :', leksi
     ENDDO
 99  CONTINUE

Τώρα όμως την λέξη που διαβάζει πού πάει και την γράφει??
Δεν καταλαβαίνω καλά τι θέλεις να πεις, ίσως πρέπει να μας εξηγήσεις τη λογική σου... Στην οθόνη τη γράφει (όπως λες).

 

Τώρα....για να διαβάζει κάθε φορά διαφορετική λέξη(ίσως με συνάρτηση ...κατι σαν την rand στην c??) αλλά και να μπορεί να προσθέτει και να αφαιρεί λέξεις από το αρχείο πώς θα γίνει???
Για τυχαίους αριθμούς θέλει λίγο ψάξιμο, πάντως συνήθως υπάρχουν έτοιμες functions/subroutines. Εχω δεί RAND, RANDOM, RANDOM_NUMBER και αρχικοποίηση (randomize...) με κάτι σαν CALL SRAND() ή CALL RANDOM_SEED(). Στο φινάλε ...φτιάχνουμε μια γεννήτρια (ψευδο)τυχαίων, δεν είναι τρομερό.

Γα το άλλο (την τυχαία προσπέλαση στο αρχείο), θες περισσότερη δουλειά. Τα αρχεία κειμένου η FORTRAN, συνήθως τα χειρίζεται σειριακά (γραμμή-γραμμή). Για να τα προσπελάσει δυναμικά (δλδ.: Διάβασε τη γραμμή τάδε) θέλει συνήθως δήλωση στο OPEN π.χ.

>       OPEN (3,FILE='FDIR', ACCESS='DIRECT', RECL=20)
      READ (3,*, REC=3) leksi

Κάτι ανάλογο θάχει η υλοποίηση που δουλεύεις (ίσως με π.χ. ACCESS='DYNAMIC'). Η παράμετρος RECL=20 δηλώνει το μήκος κάθε εγγραφής, συνήθως είναι απαραίτητη σε αρχεία αυτού του τύπου και άν είναι πρέπει να δηλώνεται εξαρχής στη φάση της δημιουργίας του αρχείου. Φυσικά το REC=3 στη READ, σημαίνει "διάβασε την 3η εγγραφή" και θα μπορούσαμε αντί 3 να βάλουμε μια μεταβλητή NREC.

 

Καλό ψάξιμο και σε παρακαλώ, μην διστάσεις να ρωτήσεις άν κάπου σε μπέρδεψα. Αν πάλι κάποιος συνομήλικος :-) θυμάται καλύτερα τη FORTRAN ή ξέρει την συγκεκριμένη έκδοση, ας τον βοηθήσει τον άνθρωπο. Πάνε κάτι τέρμινα από τότε που έγραψα σε F. κάτι σοβαρό και η τελευταία επέμβασή μου σε εφαρμογή είναι τόσο πρόσφατη, που νόμιζα ότι η Visual Fortran είναι της Sun. Τελικά είναι της DEC.

Δημοσ.

Απο αυτά που κατάλαβα βελτιωσα τον κωδικα ως εξης :

>       PROGRAM paixnidi  
        CHARACTER*20 leksi
 INTEGER a

        OPEN(10,FILE='kremala.txt')
 DO
        READ(10,*,END=99) leksi
        WRITE(*,*)"H leksh einai :", leksi
 ENDDO
99	 CONTINUE
 CLOSE(10)
 OPEN(11,FILE='kremala.txt',ACCESS='DIRECT')
 WRITE(*,*)"Pes mou ton ari8mo ths leksis pou 8es na epileksw"
 READ (*,*) a
 READ(11,REC=a) leksi
 WRITE(*,*)"H leksh einai :", leksi
 CLOSE(11) 
        END

 

Το θέμα είναι πως μόλις το τρέχω και φτάνει στο σημείο να ζητάει τον αριθμό τησ λέξης , και δίνω έναν αριθμό,τοτε το πρόγραμμα τερματίζει βγάζοντας τα εξής :

cdue: formatted io not allowed

apparent state: unit 11 named kremala.txt

last format: list io

lately reading direct unformatted external IO

 

abnormal program termination

 

>READ(11,REC=a) leksi

NREC δέν δέχεται.

Δημοσ.
...τοτε το πρόγραμμα τερματίζει βγάζοντας τα εξής :

cdue: formatted io not allowed

apparent state: unit 11 named kremala.txt

last format: list io

lately reading direct unformatted external IO

 

abnormal program termination

Υποπτεύομαι ότι είναι αυτό ακριβώς που σου έλεγα -όχι με τόση σαφήνεια όντως- στο προηγούμενο μήνυμα:
Η παράμετρος RECL=20 δηλώνει το μήκος κάθε εγγραφής' date=' συνήθως είναι απαραίτητη σε αρχεία αυτού του τύπου και [u']άν είναι[/u] πρέπει να δηλώνεται εξαρχής στη φάση της δημιουργίας του αρχείου.
Για να σου επιτρέψει δηλαδή ACCESS='DIRECT', πρέπει να δημιουργήσεις με ανάλογο τρόπο το αρχείο κι όχι να το επιχειρείς σε ένα απλό Text File.

Δεν είναι τραγικό: Με βάση τον κώδικά σου, προσθέτω μια Subroutine που αναλαμβάνει τη μετατροπή από το txt που προφανώς έχεις, στο kremala.dat, που είναι το αρχείο που θα χρησιμοποιεί το κυρίως πρόγραμμα. Φυσικά, από ένα σημείο και μετά (μόλις δουλέψουν οι εντολές χειρισμού του kremala.dat) η κλήση αυτής της ρουτίνας είναι περιττή.

Αν δεν δουλέψει το STATUS='REPLACE', δοκίμασε STATUS='NEW' την πρώτη φορά και STATUS='OLD' από κεί και πέρα.

Το ACTION='WRITE' δεν είναι τόσο απαραίτητο, περισσότερο ψάχνομαι αν δέχεται την παράμετρο η έκδοση που δουλεύεις, ώστε να παίξεις με κάτι σαν ACTION='READWRITE'. (Αν δεν παίζει, δοκίμασε και MODE='WRITE').

 

Το Κυρίως Πρόγραμμα είναι μάλλον απλό, με φοβίζει περισσότερο η χρήση του READ(...,END=99) στο αρχείο τυχαίας προσπέλασης. Μια και δεν φαίνεται να έχεις προβλημα στο DO...ENDDO, πάμε ένα βήμα ακόμη με αυτό το DO WHILE (.NOT.EOF(10)) που γράφω.

Αν δεν τρέχει τίποτε από τα δύο...Μου λές ότι δεν δέχεται το NREC (?!?) Λές να είναι καμια ενσωματωμένη μεταβλητή που μετράει records και πολεμάμε χωρίς λόγο;

Για κάνε μια προσπάθεια με τον κώδικα που ακολουθεί και το συζητάμε.

>      PROGRAM paixnidi  
     CHARACTER*20 leksi
     INTEGER a
     CALL FTRANS
     NREC=0
     OPEN(10,FILE='kremala.dat',ACCESS='DIRECT',RECL=20)
     DO WHILE (.NOT.EOF(10))
          NREC=NREC+1
          READ(10,REC=NREC) leksi
          WRITE(*,*)"H leksh einai :", leksi
     ENDDO
     CLOSE(10)
     OPEN(10,FILE='kremala.dat',ACCESS='DIRECT',RECL=20)
     WRITE(*,*)"Pes mou ton ari8mo ths leksis pou 8es na epileksw"
     READ (*,*) a
     IF (A.LE.NREC) THEN
         READ(10,REC=a) leksi
         WRITE(*,*)"H leksh einai :", leksi
     ELSE
  WRITE(*,*)"a MEGALYTERO APO nrec"
     ENDIF
     CLOSE(10)
     STOP
     END
C
     SUBROUTINE FTRANS
     CHARACTER*20 leksi
     IREC=0
     OPEN(10,FILE='kremala.txt')
     OPEN(11,FILE='kremala.dat',ACCESS='DIRECT',STATUS='REPLACE',ACTION
    *    ='WRITE',RECL=20)
     DO
         READ(10,*,END=99) leksi
         IREC=IREC+1
         WRITE(11,REC=IREC)leksi
         WRITE(*,*)LEKSI
    ENDDO
99 CONTINUE
    CLOSE(10)
    CLOSE(11)
    RETURN
    END

Καλή τύχη.

Δημοσ.

Φίλε ευχαριστω πάρα πολύ που ασχολείσαι....

Ειδα τον κώδικά σου αλλα στο compile, βγάζει κάτι ακυρα errors σε κάτι κόμματα.

Κουφά πράγματα.Τέλος πάντων πάω για υπνο και τα λέμε αυριο πιο αναλυτικά.

Ευχαριστω και πάλι

Δημοσ.

Λοιπόν τον κώδικά σου τον κατάλαβα.

Παρόλα αυτά δεν κατάφερα να διορθωσω πολλα απο τα προβληματα.

Μετά απο compile βγάζει αυτα τα σφάλματα

DO WHILE (.NOT.EOF(10))

1 2

.NOT. operator at (1) must operate on subexpression of logical type, but the sub

expression at (2) is not of logical type

kremala.f: In subroutine `ftrans':

kremala.f:30:

OPEN(11,FILE='kremala.dat',ACCESS='DIRECT',STATUS='REPLACE',ACTIO

^

Invalid form for OPEN statement at (^)

kremala.f:31:

t ='WRITE',RECL=20)

^

Invalid form for assignment statement at (^)

kremala.f:28:

IREC=0

1

kremala.f:42: (continued):

END PROGRAM paixnidi

2

Statement at (2) invalid in context established by statement at (1)

kremala.f:28:

IREC=0

1

kremala.f:43: (continued):

CHARACTER*20 leksi

2

Statement at (2) invalid in context established by statement at (1)

kremala.f:28:

IREC=0

1

kremala.f:44: (continued):

INTEGER a

2

Statement at (2) invalid in context established by statement at (1)

kremala.f:38:

99 CONTINUE

1

kremala.f:51: (continued):

99 CONTINUE

2

Label 99 already defined at (1) when redefined at (2)

 

Είναι προφανές πως δεν δουλεύει η DO WHILE (.NOT.EOF(10))

Την έτρεξα και στο σπιτι και σε πανεπιστήμιο

 

Κατι που θα ήθελα να σε ρωτησω ειναι αν χρησιμοποιείς irc Μηπως διευκόλυνε...

Στην τελική ίσως σου στείλω την άσκηση μπας και μπορέσεις να την δείς ολοκληρωμένη

Δημοσ.

Ξεκινώντας από το τέλος, δυστυχώς δεν χρησιμοποιώ IRC. Στη δουλειά είμαι πίσω από μια συστοιχία firewalls κι εδώ που βρίσκομαι για Σ/Κ έχω μια σύνδεση που κυριολεκτικά σέρνεται.

 

Στα λάθη, ας ξεκινήσουμε από το (μάλλον) προφανές: Η γραμμή OPEN(11,...,ACTION είναι οριακά στριμωγμένη στα όρια της Fixed Format Fortran, ανάμεσα στις στήλες 7 και 72. Το ότι κόβεται στο "ACTIO" με υποψιάζει ότι μάλλον έχει μετακινηθεί μια στήλη δεξιά στις μεταφορές από τον δικό μου editor στο forum κι από κεί στον δικό σου.

Η υποψία ενισχύεται από το μήνυμα στην γραμμή που ακολουθεί: Κανονικά, αν το "*" είναι στη στήλη 6 θα το μεταφράσει σαν ένδειξη συνέχειας της προηγούμενης εντολής (...ACTION='WRITE',RECL=20). Το ότι το αγνοεί, σημαίνει, είτε ότι κι αυτό έχει μετακινηθεί, είτε ότι ο compiler που χρησιμοποιείς δεν δέχεται το "*" αλλά κάτι άλλο. (Τι στην οργή είναι το standard? Ισως +, - ή &, ρίξε μια ματιά αν έχεις το manual).

Εννοείται ότι αν έχεις δυνατότητα να γράψεις σε free format, απλά ενώνεις τις δύο γραμμές.

 

Για τη DO WHILE (.NOT.EOF(10)) θα συμφωνήσω. Είναι προφανές πως δεν δουλεύει, θα είδες άλλωστε ότι την έγραψα με μεγάλη επιφύλαξη. Αν φταίει η EOF, μόνο το manual θα μας σώσει, να δούμε πώς αναγνωρίζει end of file σε direct acces. (Εκτός αν είμαστε τυχεροί και παίζει κι εδώ το END=... της σειριακής προσπέλασης). Αν πάλι δεν αναγνωρίζει το WHILE τα πράγμα τα είναι πιό απλά: Αντικαθιστούμε το το DO WHILE...ENDDO με το παρακάτω:

>   80 IF (EOF(10)) GOTO 81
        NREC=NREC+1
        READ(10,REC=NREC) leksi
        WRITE(*,*)"H leksh einai :", leksi
        GOTO 80
  81 CONTINUE

Κάποιοι θα διαβάσουν GOTO και θα βγάλουν σπυριά, αλλά σε βεβαιώνω ότι σε τέτοιες περιπτώσεις δεν πειράζει καθόλου.

 

Τα άλλα δεν τα πολυκαταλαβαίνω: Βρίσκει την 99 CONTINUE, "redefined". Μήπως κατά λάθος την έχεις γράψει δύο φορές;

Για το συνδυασμό IREC=0 / INTEGER a / CHARACTER*20 leksi δεν καταλαβαίνω τί δεν του πάει καλά, πολύ περισσότερο που δεν δείχνει να ενοχλεί ο αντίστοιχος με NREC=0 στο κυρίως πρόγραμμα. Δες μήπως έχεις αλλάξει την σειρά (κάποιες εκδόσεις θέλουν να ολοκληρώνονται οι δηλώσεις πρίν από οποιαδήποτε εντολή) και ξαναγράψε τις εντολές, μήπως στην προσπάθεια να τα στοιχίσω στο post, μου ξέφυγε κανένας ελληνικός χαρακτήρας. Θα μπορούσε ακόμη να φταίει ότι έχουν να κάνουν με I/O στο αρχείο τυχαίας προσπέλασης, οπότε αφού δεν δούλεψε η OPEN, τα χτυπάει κι αυτά, έχω δει Fortran Compilers να βγάζουν δεκάδες λάθη και μόλις κάνεις μια-δυό διορθώσεις να τα βλέπουν όλα ωραία και καλά.

 

Τελειώνοντας: Δες κυρίως τη στοίχιση: Τα labels (80,81,99) στις στήλες 1-5, ο χαρακτήρας συνέχειας (ελπίζω να πάρει το *) στην 6 και οι άλλες ανάμεσα στις 7-72. Επειδή έχω δει πολλά, οι PROGRAM, STOP, END, SUBROUTINE και RETURN ας αρχίζουν ακριβώς στην 7. Υστερα δες λίγο και το EOF και τα ξανασυζητάμε.

Καλή τύχη.

Δημοσ.

Με πολύ ξενύχτι και "φλασιές" κατάφερα να διορθώσω λιγάκι τα πράγματα

Δές τον κώδικα αλλά αυτό το EOF δεν μπόρεσα ακόμα να το βρώ.

>       PROGRAM paixnidi
      CHARACTER*20 leksi
      INTEGER a
C      CALL FTRANS
      NREC=0
      OPEN(10,FILE='kremala.dat',ACCESS='DIRECT',RECL=20)
80     IF (EOF(10)) GOTO 81
      NREC=NREC+1
      READ(10,REC=NREC) leksi
      WRITE(*,*)"H leksh einai :", leksi
      GOTO 80
81     CONTINUE
      CLOSE(10)
      OPEN(10,FILE='kremala.dat',ACCESS='DIRECT',RECL=20)
      WRITE(*,*)"Pes mou ton ari8mo ths leksis pou 8es na epileksw"
      READ (*,*) a
      IF (A.LE.NREC) THEN
         READ(10,REC=a) leksi
         WRITE(*,*)"H leksh einai :", leksi
      ELSE
  WRITE(*,*)"a MEGALYTERO APO nrec"
      ENDIF
      CLOSE(10)
      STOP
      CALL FTRANS
      OPEN(10,FILE='kremala.txt')
 DO
        READ(10,*,END=100) leksi
        WRITE(*,*)"H leksh einai :", leksi
 ENDDO
100	 CONTINUE
 CLOSE(10)
 OPEN(11,FILE='kremala.txt',ACCESS='DIRECT')
 WRITE(*,*)"Pes mou ton ari8mo ths leksis pou 8es na epileksw"
 READ (*,*) a
 READ(11,REC=a) leksi
 WRITE(*,*)"H leksh einai :", leksi
 CLOSE(11)

      END

 

Τέλος πάντων θα το ψάξω(google)

Σου στέλνω και ένα προχειρο διάγραμμα ροής με την συνέχεια της άσκησης για να δεις πώς το έχω σκεφτεί.

 

Ελπίζω να φαίνεται το συννημένο...

post-26287-129062921555_thumb.jpg

Δημοσ.
Δές τον κώδικα αλλά αυτό το EOF δεν μπόρεσα ακόμα να το βρώ....

Ελπίζω να φαίνεται το συννημένο...

Αν δεν το έχεις βρεί (υπάρχει manual?) φοβάμαι ότι εκεί είναι το πρόβλημα. Σε τελευταία ανάλυση, αφήνουμε το αρχείο σειριακό.

Το συνημμένο, φαίνεται, αλλά ο κώδικας έχει σίγουρα πρόβλημα: H ftrans εκεί που καλείται δεν έχει νόημα και δεν δηλώνεται πουθενά :-(

Δημοσ.

Άρχισα απο την αρχη το προγραμμα και εχω γράψει τα εξής αλλα δεν μπορώ να συνεχίσω.

>       PROGRAM kremala
CHARACTER*20 leksi
CHARACTER*20 pleksi
CHARACTER GRAMMA
INTEGER nleksi,TEMP,TEST,BRIKA,APOTYXIES

TEMP=0
WRITE(*,*) 'POSES APOTYTXIES;'
READ(*,*) APOTYXIES
c        WRITE(*,*)'APOTYXIES :', APOTYXIES

OPEN(1,FILE='kremala.txt')
WRITE (*,*) 'epelekse mia leksi'
READ (*,*) nleksi
DO 1,i=1,nleksi
READ(1,*) leksi
1	CONTINUE
WRITE(*,*) leksi
CLOSE(1)


DO 2,I=1,20
	IF(ICHAR(LEKSI(I:I)).EQ.32) THEN
		TEMP=I-1
		GOTO 3
	ENDIF
2	CONTINUE
3       CONTINUE

BRIKA=TEMP-2
c	WRITE(*,*)TEMP

PLEKSI(1:1)=LEKSI(1:1)
PLEKSI(2:TEMP)='------------------'
PLEKSI(TEMP:TEMP)=LEKSI(TEMP:TEMP)
PLEKSI(TEMP+1:20)='              '
WRITE(*,*)PLEKSI

5	WRITE(*,*)'Dose mou ena gramma:'
READ(*,*) GRAMMA

DO 4,I=2,TEMP-1
	IF(ICHAR(LEKSI(I:I)).EQ.ICHAR(GRAMMA))THEN
		PLEKSI(I:I)=GRAMMA
		BRIKA=BRIKA-1
               ENDIF
4	CONTINUE
WRITE(*,*)PLEKSI
IF(BRIKA.GT.0) GOTO 5

       WRITE(*,*)'Mpravo kerdises.H leksi htan h :  ',PLEKSI

END

Μεχρι εδώ δουλεύει μια χαρά.Και θέλω να συνεχίσω σύμφωνα με το διαγραμμα ροής που υπάρχει παραπάνω.

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...