2009-08-11 10 views

Odpowiedz

48

można napisać do jednostki, ale można też napisać do łańcucha

program foo 
    character(len=1024) :: filename 

    write (filename, "(A5,I2)") "hello", 10 

    print *, trim(filename) 
end program 

Uwaga (jest to drugi trik Rozmawiałem o), które można również zbudować ciąg formatu programowo.

program foo 

    character(len=1024) :: filename 
    character(len=1024) :: format_string 
    integer :: i 

    do i=1, 10 
     if (i < 10) then 
      format_string = "(A5,I1)" 
     else 
      format_string = "(A5,I2)" 
     endif 

     write (filename,format_string) "hello", i 
     print *, trim(filename) 
    enddo 

end program 
+12

dwie uwagi: - nie trzeba rozróżniać od wartości I; format (I0) wypisze liczbę całkowitą bez spacji; również, jeśli chcesz mieć stałą szerokość i dopełnienie zerami (np. "output001.txt"), musisz użyć (I0.3) - format (A5I2) jest nieprawidłowy Fortran zgodnie z jakąkolwiek normą, ponieważ specyfikatory formatu są należy rozdzielić przecinkami: (A5, I2) –

+0

Cóż, to było w celach edukacyjnych, a nie miało być rozwiązaniem. Generalnie używam dopełnień zer (jak to ładnie się sortuje), ale I0 rzeczy, o których nie wiedziałem. Dzięki!! (naprawiono przecinki, myślę, że mój styl był stary, wciąż akceptowany) –

+0

@ F'x dzięki za komentarz, naprawdę użyteczny. Rzeczywiście nawet przycinanie nie zadziała, jeśli liczba k cyfr nie będzie równa "(Ik)" w formacie, więc po prostu użyj "(I0)", aby nie trzeba było dostosowywać formatu. – gluuke

-4

Oto moje podprogramowe podejście do tego problemu. przekształca liczbę całkowitą z zakresu 0: 9999 jako znak. Na przykład INTEGER 123 przekształca się w postać 0123. mam nadzieję, że to pomoże.

P.S. - przepraszam za komentarze; one sensu w rumuńskim: P

subroutine nume_fisier (i,filename_tot) 

    implicit none 
    integer :: i 

    integer :: integer_zeci,rest_zeci,integer_sute,rest_sute,integer_mii,rest_mii 
    character(1) :: filename1,filename2,filename3,filename4 
    character(4) :: filename_tot 

! Subrutina ce transforma un INTEGER de la 0 la 9999 in o serie de CARACTERE cu acelasi numar 

! pentru a fi folosite in numerotarea si denumirea fisierelor de rezultate. 

if(i<=9) then 

    filename1=char(48+0) 
    filename2=char(48+0) 
    filename3=char(48+0) 
    filename4=char(48+i) 

elseif(i>=10.and.i<=99) then 

    integer_zeci=int(i/10) 
    rest_zeci=mod(i,10) 
    filename1=char(48+0) 
    filename2=char(48+0) 
    filename3=char(48+integer_zeci) 
    filename4=char(48+rest_zeci) 

elseif(i>=100.and.i<=999) then 

    integer_sute=int(i/100) 
    rest_sute=mod(i,100) 
    integer_zeci=int(rest_sute/10) 
    rest_zeci=mod(rest_sute,10) 
    filename1=char(48+0) 
    filename2=char(48+integer_sute) 
    filename3=char(48+integer_zeci) 
    filename4=char(48+rest_zeci) 

elseif(i>=1000.and.i<=9999) then 

    integer_mii=int(i/1000) 
    rest_mii=mod(i,1000) 
    integer_sute=int(rest_mii/100) 
    rest_sute=mod(rest_mii,100) 
    integer_zeci=int(rest_sute/10) 
    rest_zeci=mod(rest_sute,10) 
    filename1=char(48+integer_mii) 
    filename2=char(48+integer_sute) 
    filename3=char(48+integer_zeci) 
    filename4=char(48+rest_zeci) 

endif 

filename_tot=''//filename1//''//filename2//''//filename3//''//filename4//'' 
return 
end subroutine nume_fisier 
+6

To jest bardzo zła odpowiedź. Zgodnie z przyjętą odpowiedzią, Fortran zapewnia mechanizm zapisywania wartości liczby całkowitej w zmiennej znakowej; wszystkie te manipulacje przy kodowaniu i dekodowaniu indeksów znaków są okropnym hackem, który nie służy żadnemu pożytecznemu celowi. –

+2

@HighPerformanceMark Jeśli chodzi o jego imię, ten kod wygląda całkiem sensownie. – PVitt

13

Znacznie łatwiej IMHO rozwiązanie ...................

character(len=8) :: fmt ! format descriptor 

fmt = '(I5.5)' ! an integer of width 5 with zeros at the left 

i1= 59 

write (x1,fmt) i1 ! converting integer to string using a 'internal file' 

filename='output'//trim(x1)//'.dat' 

! ====> filename: output00059.dat 
+0

KOREKCJA: filename = 'output' // trim (x1) // 'dat dat – Alejandro

+0

może po prostu być moim kompilatorem, ale potrzebowałem zadeklarować zmienną znaku dla napisanego łańcucha wyjściowego (np. 'Character (5) x1 '). dzięki! – ryanjdillon

8

Więc tutaj jest prosta funkcja, która powróci lewy uzasadnione wersję ciąg liczb całkowitych:

character(len=20) function str(k) 
! "Convert an integer to string." 
    integer, intent(in) :: k 
    write (str, *) k 
    str = adjustl(str) 
end function str 

A oto kod testowy:

program x 
integer :: i 
do i=1, 100 
    open(11, file='Output'//trim(str(i))//'.txt') 
    write (11, *) i 
    close (11) 
end do 
end program x 
2

Dla skróconej wersji. Jeżeli wszystkie wskaźniki są mniejsze niż 10, a następnie użyć następujących:

do i=0,9 
    fid=100+i 
    fname='OUTPUT'//NCHAR(i+48) //'.txt' 
    open(fid, file=fname) 
    !.... 
end do 

Dla ogólnego wersji:

character(len=5) :: charI 
do i = 0,100 
    fid = 100 + i 
    write(charI,"(A)"), i 
    fname ='OUTPUT' // trim(charI) // '.txt' 
    open(fid, file=fname) 
end do 

To wszystko.

+0

Po nawiasie zamykającym w instrukcji zapisu nie powinno być przecinków. ((write (charI, "(A)") i)) Dzięki, używam tej sugestii. – mamun

+0

Domyślnie nie ma przecinka, ale znalazłem go dobrze, jeśli dodany został dodatkowy przecinek, podobny do ((print *, i)). – kayneo

0

Próbowałem już @Alejandro i @ user2361779 już, ale daje mi niezadowalający wynik, taki jak file 1.txt lub file1 .txt zamiast file1.txt. Jednak i znalezienie lepszego rozwiązania:

... 
integer :: i 
character(len=5) :: char_i  ! use your maximum expected len 
character(len=32) :: filename 

write(char_i, '(I5)') i  ! convert integer to char 
write(filename, '("path/to/file/", A, ".dat")') trim(adjustl(char_i)) 
... 

Objaśnienie:

np ustawić i = 10 i write(char_i, '(I5)') i

char_i    gives " 10" ! this is original value of char_i 

adjustl(char_i)  gives "10 " ! adjust char_i to the left 

trim(adjustl(char_i)) gives "10" ! adjust char_i to the left then remove blank space on the right 

myślę, że jest to najprostsze rozwiązanie, które daje długości dynamicznego pliku bez starszych spacjami z Integer na ciąg procesu konwersji.

+1

Użycie 'I0' jako deskryptora edycji byłoby znacznie prostsze:' write (filename, '("ścieżka/do/plik /", I0, ".dat") ") i'. Jest to wspomniane wcześniej w tym pytaniu tylko w komentarzach, więc może być dodane. – francescalus

+0

Dziękuję @francescalus, nie zauważyłem tego komentarza. Następnie zostawiłem moją odpowiedź jako alternatywne rozwiązanie. może to być przydatne w niektórych przypadkach. – fronthem

2

Już pokazałem to gdzie indziej na SO (How to use a variable in the format specifier statement?, a nie dokładny duplikat IMHO), ale myślę, że warto go tutaj umieścić. Możliwe jest użycie techniki z innych odpowiedzi na to pytanie, aby prostą funkcję

function itoa(i) result(res) 
    character(:),allocatable :: res 
    integer,intent(in) :: i 
    character(range(i)+2) :: tmp 
    write(tmp,'(i0)') i 
    res = trim(tmp) 
end function 

których można używać po bez martwienia się o przycinanie i lewej uruchamiania i bez pisania do zmiennej tymczasowej:

OPEN(1, FILE = 'Output'//itoa(i)//'.TXT') 

Wymaga Fortran 2003 ze względu na przydzielany ciąg.

-1

Aby przekonwertować liczbę całkowitą na łańcuch:

integer :: i  
character* :: s  
if (i.LE.9) then 
    s=char(48+i)  
else if (i.GE.10) then 
    s=char(48+(i/10))// char(48-10*(i/10)+i)  
endif 
+0

Co jeśli 'i' jest duży? – francescalus

Powiązane problemy