2013-02-27 2 views
0

J'essaye d'utiliser fortran pour écrire un fichier délimité par des virgules pour l'importer dans un autre paquet commercial. Le problème est que j'ai un nombre inconnu de colonnes de données. Ma sortie doit ressembler à ceci:Instruction au format avec des colonnes inconnues

a_string,a_float,a_different_float,float_array_elem1,float_array_elem2,...,float_array_elemn 

qui conduirait à quelque chose qui pourrait ressembler à ceci:

L1080,546876.23,4325678.21,300.2,150.125,...,0.125 
L1090,563245.1,2356345.21,27.1245,...,0.00983 

J'ai trois questions. Premièrement, je préférerais que les éléments soient étroitement groupés (largeur de colonne variable), deux, je ne sais pas comment définir un nombre variable d'éléments de tableau dans l'instruction de format, et trois, les éléments de tableau peuvent couvrir une large gamme ... peut-être 12 ordres de grandeur. Le code suivant fait conceptuellement ce que je veux, mais la variable « n » et l'absence de définition de la colonne de largeur renvoie une erreur (bien sûr):

WRITE(50,900) linenames(ii),loc(ii,1:2),recon(ii,1:n) 
900 FORMAT(A,',',F,',',F,n(',',F)) 

(Je dois souligner que n est fixé à l'exécution .) L'instruction write fait ce que je veux quand je fais WRITE (50, *), sauf qu'elle est délimitée par la largeur.

Je pense que ce fil a presque répondu à ma question, mais j'ai été assez confus: SO. En ce moment j'ai un script shell avec awk corrigeant le problème, mais cette solution est ... inélégante. Je pourrais faire quelques manipulations pour faire de la sortie une chaîne, et ensuite l'écrire, mais je préférerais éviter cette option si possible. Je le fais dans Fortran 90 mais j'aime essayer de garder mon code aussi rétrocompatible que possible.

+0

Je devrais également noter que la raison pour laquelle je voudrais des colonnes serrées est double: une, qui est l'entrée désirée au prochain programme, et deux, taille. Il peut y avoir plusieurs millions de lignes dans le fichier de sortie résultant, avec plusieurs dizaines de colonnes. Les espaces font la différence! Merci –

Répondre

1

le format proche de ce que vous voulez est f0.3, cela ne donnera pas d'espaces et un nombre fixe de décimales. Je pense que si vous voulez également supprimer les zéros à la fin, vous devrez faire un bon travail. Le 'n' dans votre instruction write peut être plus grand que le nombre de valeurs de données, donc une approche (old school) consiste à y mettre un grand nombre, par exemple 100000. Fortran moderne a une certaine syntaxe pour spécifier une répétition indéfinie , je suis sûr que quelqu'un l'offrira.

---- modifier la répétition illimitée est comme vous pouvez le deviner un asterisk..and est evideltly « flambant neuf » dans F2008

1

Afin de vous assurer qu'aucun espace se produit entre les entrées dans votre ligne , vous pouvez les écrire séparément dans des variables de caractères, puis les imprimer en utilisant la fonction adjustl() Fortran:

program csv 
    implicit none 

    integer, parameter :: dp = kind(1.0d0) 
    integer, parameter :: nn = 3 
    real(dp), parameter :: floatarray(nn) = [ -1.0_dp, -2.0_dp, -3.0_dp ] 
    integer :: ii 
    character(30) :: buffer(nn+2), myformat 

    ! Create format string with appropriate number of fields. 
    write(myformat, "(A,I0,A)") "(A,", nn + 2, "(',',A))" 
    ! You should execute the following lines in a loop for every line you want to output 
    write(buffer(1), "(F20.2)") 1.0_dp ! a_float 
    write(buffer(2), "(F20.2)") 2.0_dp ! a_different_float 
    do ii = 1, nn 
    write(buffer(2+ii), "(F20.3)") floatarray(ii) 
    end do 
    write(*, myformat) "a_string", (trim(adjustl(buffer(ii))), ii = 1, nn + 2) 

end program csv 

la démonstration est au-dessus pour une seule ligne de sortie, mais vous pouvez facilement écrire une boucle autour du bloc approprié l'exécuter pour toutes vos lignes de sortie. En outre, vous pouvez choisir un format numérique différent pour les différentes entrées, si vous le souhaitez.

+0

une fois ici, vous pouvez facilement faire un pas de plus et dépouiller les zéros de fin (probly écrire une fonction de trim qui réduit l'espace ou 0.) – agentp

Questions connexes