2009-04-07 20 views
7

Ho una domanda su Fortran 77 e non sono riuscito a trovare una soluzione.Array of Strings in Fortran 77

Sto cercando di memorizzare un array di stringhe definite come segue:

character matname(255)*255 

Quale è una matrice di 255 stringhe di lunghezza 255.

Più tardi ho letto l'elenco dei nomi da un di file e ho impostato il contenuto della matrice in questo modo:

matname(matcount) = mname 

EDIT: in realtàmname valore è harcoded come mname = 'AIR' di tipo character*255, è un parametro di una funzione matadd() che esegue la riga precedente. Ma questo è solo per il test, in futuro verrà letto da un file.

Più tardi voglio stampare con:

write(*,*) matname(matidx) 

ma sembra per stampare tutti i 255 caratteri, si stampa la stringa ho assegnato e un sacco di immondizia.

  • Quindi questa è la mia domanda, come posso sapere la lunghezza della stringa memorizzata?
  • Devo avere un altro array con tutte le lunghezze?
  • E come posso sapere che la lunghezza della stringa è stata letta?

Grazie.

+1

+1 - Fortran? sei serio? –

+1

@ Ian - Perché no? – Rook

risposta

4

La funzione Timotei pubblicata ti darà la lunghezza della stringa purché la parte della stringa a cui sei interessato contenga solo spazi, che, se stai assegnando i valori nel programma shou È vero come FORTRAN dovrebbe inizializzare le variabili da vuotare e per i caratteri che significa uno spazio.

Tuttavia, se si sta effettuando la lettura da un file, è possibile rilevare altri caratteri di controllo alla fine delle righe (in particolare caratteri di ritorno a capo e/o avanzamento riga, \ r e/o \ n a seconda del sistema operativo) . Dovresti anche buttarli nella funzione per ottenere la lunghezza corretta della stringa. Altrimenti potresti ottenere delle buffe dichiarazioni di stampa man mano che quei caratteri vengono stampati.

Ecco la mia versione della funzione che verifica la presenza di spazi bianchi alternati alla fine oltre agli spazi.

function strlen(st) 
    integer   i,strlen 
    character   st*(*) 
    i = len(st) 
    do while ((st(i:i).eq.' ').or.(st(i:i).eq.'\r').or. 
+ (st(i:i).eq.'\n').or.(st(i:i).eq.'\t')) 
    i = i - 1 
    enddo 
    strlen = i 
    return 
    end 

Se ci sono altri caratteri nella sezione "spazzatura", questo non funzionerà ancora completamente.

Supponendo che funziona per i dati, tuttavia, è possibile quindi modificare la sua dichiarazione di scrittura per assomigliare a questo:

write(*,*) matname(matidx)(1:strlen(matname(matidx))) 

e sarà stampare solo la stringa effettiva.

Per quanto riguarda la necessità di utilizzare un altro array per contenere le lunghezze della stringa, questo dipende da voi. la funzione strlen() è O (n) mentre cercare la lunghezza in una tabella è O (1). Se ti ritrovi a calcolare spesso le lunghezze di queste stringhe statiche, potrebbe migliorare le prestazioni per calcolare la lunghezza una volta che vengono letti, archiviarli in una matrice e cercarli se ne hai bisogno. Tuttavia, se non si nota il rallentamento, non me ne preoccuperei.

+0

Ho dovuto modificare la definizione del tipo della funzione ricevendo la stringa come parametro per: 'character mname * (*)'. Prima, la fine di quella variabile era spazzatura casuale, ora è riempita di spazi. Grazie per la spiegazione, è stato molto chiarificatore. Inoltre non sapevo della * notazione. – Siu

5

È possibile utilizzare questa funzione per ottenere la lunghezza (senza coda vuota)

integer function strlen(st) 
     integer  i 
     character  st*(*) 
     i = len(st) 
     do while (st(i:i) .eq. ' ') 
     i = i - 1 
     enddo 
     strlen = i 
     return 
     end 

Got da qui: http://www.ibiblio.org/pub/languages/fortran/ch2-13.html

PS: Quando si dice: matname (matidx) ottiene l'intera stringa (256) chars ... quindi quella è la tua stringa più spazi vuoti o immondizia

+0

+1 ma vorrei che potesse essere di più. –

+0

Grazie anche a te, vorrei votarti ma non ho ancora abbastanza reputazione. – Siu

1

seconda del compilatore in uso, può essere possibile utilizzare la funzione intrinseca trim() per rimuovere eventuali leader/spazi finali da una stringa, poi elaborarlo come di consueto, cioè

character(len=25) :: my_string 
my_string = 'AIR' 
write (*,*) ':', trim(my_string), ':' 

dovrebbe stampare :AIR:.

Modifica: Ancora meglio, sembra che ci sia una funzione len_trim() che restituisce la lunghezza di una stringa dopo che è stata ritagliata.

0

intel e Compaq Visual Fortran hanno la funzione intrinseca LEN_TRIM (STRING) che restituisce la lunghezza senza spazi vuoti o spazi.

Se si desidera eliminare gli spazi iniziali o spazi, usare "Regola di sinistra", cioè ADJUSTF (STRING)

In questi FORTRANs rilevo anche una funzione utile: se si passa una stringa a una funzione o subroutine come un argomento, e all'interno della subroutine è dichiarato come CHARACTER * (*), quindi utilizzando la funzione LEN (STRING) nella subroutine fa retromarcia la lunghezza effettiva della stringa passata, e non la lunghezza della stringa dichiarata nel programma chiamante .

Esempio: PERSONAGGIO * 1000 STRING

 . 
     . 

    CALL SUBNAM(STRING(1:72) 

    SUBROUTINE SYBNAM(STRING) 
    CHARACTER*(*) STRING 
    LEN(STRING) will be 72, not 1000 
+0

L'uso di una struttura per la stringa e la sua lunghezza, a volte ha senso. – Holmz