2009-04-07 4 views
7

J'ai une question à propos de Fortran 77 et je n'ai pas été en mesure de trouver une solution.Tableau de chaînes dans Fortran 77

Je suis en train de stocker un tableau de chaînes définies comme les suivantes:

character matname(255)*255 

Wich est un tableau de 255 chaînes de longueur 255.

Plus tard je lis la liste des noms d'une fichier et je mis le contenu du tableau comme celui-ci:

matname(matcount) = mname 

EDIT: en faitmname valeur est harcoded comme mname = 'AIR' de type character*255, c'est un paramètre d'une fonction matadd() qui exécute la ligne précédente. Mais ce n'est que pour tester, dans le futur il sera lu à partir d'un fichier.

Plus tard je veux l'imprimer avec:

write(*,*) matname(matidx) 

Mais il semble imprimer tous les 255 caractères, il imprime la chaîne I attribué et beaucoup de déchets.

  • Donc, c'est ma question, comment puis-je connaître la longueur de la chaîne stockée?
  • Devrais-je avoir un autre tableau avec toutes les longueurs?
  • Et comment puis-je connaître la longueur de la chaîne lue?

Merci.

+1

+1 - Fortran? es-tu sérieux? –

+1

@Ian - Pourquoi pas? – Rook

Répondre

4

La fonction Timotei posté vous donnera la longueur de la chaîne tant que la partie de la chaîne qui vous intéresse ne contient que des espaces, qui, si vous attribuez les valeurs dans le programme shou ld est vrai car FORTRAN est supposé initialiser les variables pour être vides et pour les caractères qui signifie un espace. Cependant, si vous lisez à partir d'un fichier, vous pouvez saisir d'autres caractères de contrôle à la fin des lignes (en particulier les caractères de retour chariot et/ou de saut de ligne, \ r et/ou \ n selon votre système d'exploitation) . Vous devriez également les jeter dans la fonction pour obtenir la longueur de chaîne correcte. Sinon, vous pouvez obtenir des instructions d'impression amusantes lorsque ces caractères sont également imprimés.

Voici ma version de la fonction qui vérifie les autres espaces blancs à la fin des espaces.

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 

S'il y a d'autres personnages dans la section « poubelle » ce ne fonctionne toujours pas complètement.

En supposant que cela ne fonctionne pour vos données, mais vous pouvez modifier votre déclaration d'écriture à ressembler à ceci:

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

et il affichera simplement la chaîne réelle.

Que vous utilisiez ou non un autre tableau pour conserver les longueurs de la chaîne, c'est à vous de décider. la fonction strlen() est O (n) alors que rechercher la longueur dans une table est O (1). Si vous vous trouvez souvent à calculer la longueur de ces chaînes statiques, cela peut améliorer les performances pour calculer la longueur une fois quand elles sont lues, les stocker dans un tableau et les rechercher si vous en avez besoin. Cependant, si vous ne remarquez pas le ralentissement, je ne m'inquiéterais pas.

+0

J'ai dû modifier la définition de type de la fonction recevant la chaîne en paramètre: 'character mname * (*)'. Avant, la fin de cette variable était aléatoire, maintenant elle est complétée par des espaces. Merci pour l'explication, était très éclaircissant. De plus, je ne connaissais pas la notation *. – Siu

5

Vous pouvez utiliser cette fonction pour obtenir la longueur (sans queue blanc)

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 

obtenu à partir d'ici: http://www.ibiblio.org/pub/languages/fortran/ch2-13.html

PS: Quand vous dites: matname (matidx) il obtient toute la chaîne (256) chars ... de sorte que votre chaîne plus des blancs ou des ordures

+0

+1 mais j'aimerais qu'il soit plus. –

+0

Merci aussi, je voudrais vous voter mais je n'ai toujours pas assez de réputation. – Siu

1

Selon le compilateur que vous utilisez, vous pouvez être en mesure d'utiliser la trim() fonction intrinsèque pour supprimer les espaces de premier plan/arrière d'une chaîne, puis traiter comme vous le feriez normalement, à savoir

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

devrait imprimer :AIR:.

Editer: Mieux encore, il semble qu'il existe une fonction len_trim() qui renvoie la longueur d'une chaîne après qu'elle a été rognée.

0

intel et Compaq Visual Fortran ont la fonction intrinsèque LEN_TRIM (STRING) qui retourne la longueur sans espaces ou espaces de fin.

Si vous voulez supprimer les blancs ou des espaces, utilisez « Ajuster gauche » c.-à-ADJUSTF (STRING)

Dans ces FORTRANS Je note également une fonction utile: Si vous passez une chaîne à une fonction ou sous-routine comme un argument, et à l'intérieur du sous-programme, il est déclaré comme CHARACTER * (*), puis en utilisant la fonction LEN (STRING) dans le sous-programme rétrograde la longueur de chaîne réelle passée, et non la longueur de la chaîne comme déclarée dans le programme appelant .

Exemple: CHARACTER * 1000 STRING

 . 
     . 

    CALL SUBNAM(STRING(1:72) 

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

L'utilisation d'une structure pour la chaîne et la longueur de celle-ci est parfois logique. – Holmz

Questions connexes