2011-11-28 9 views
6

¿sabe si la siguiente declaración se garantiza que es cierta según uno de los estándares fortran 90/95/2003? "Supongamos que una instrucción de lectura para una variable de caracteres tiene una línea en blanco (es decir, que contiene solo espacios en blanco y nuevos caracteres de línea) .Si el especificador de formato es un asterisco (*), continúa leyendo las líneas siguientes hasta que se encuentra la línea en blanco. Si el especificador de formato es '(A)', se sustituye una cadena en blanco a la variable de caracteres.Lectura de la declaración de lectura de Fortran más allá del final de la línea

Por ejemplo, consulte el siguiente programa mínimo y archivo de entrada.

código de programa: archivo

PROGRAM chk_read 
    INTEGER,   PARAMETER :: MAXLEN=30 
    CHARACTER(len=MAXLEN)  :: str1, str2 

    str1='minomonta' 
    read(*,*)  str1 
    write(*,'(3A)') 'str1_start|', str1, '|str1_end' 

    str2='minomonta' 
    read(*,'(A)') str2 
    write(*,'(3A)') 'str2_start|', str2, '|str2_end' 

END PROGRAM chk_read 

de entrada:

----'input.dat' content is below this line---- 

yamanakako 

kawaguchiko  
----'input.dat' content is above this line---- 

Tenga en cuenta que hay cuatro líneas en 'input.dat' y la primera y tercera líneas están en blanco (solamente contienen espacios en blanco y nuevos personajes de línea). Si funciono el programa como

$ ../chk_read <input.dat> output.dat 

Me da la siguiente salida

----'output.dat' content is below this line---- 
str1_start|yamanakako     |str1_end 
str2_start|        |str2_end 
----'output.dat' content is above this line---- 

La primera instrucción de lectura para la variable 'cadena1' parece mirar a la primera línea de 'input.dat', encuentro una línea en blanco, avance a la segunda línea, encuentre el valor del carácter 'yamanakako' y guárdelo en 'str1'.

En contraste, la segunda instrucción de lectura para la variable 'str2' parece tener la tercera línea, que está en blanco, y almacena la línea en blanco en 'str2', sin moverse a la cuarta línea.

Intenté compilar el programa con Intel Fortran (ifort 12.0.4) y GNU Fortran (gfortran 4.5.0) y obtuve el mismo resultado.

Un poco sobre el trasfondo de hacer esta pregunta: Estoy escribiendo una subrutina para leer un archivo de datos que usa una línea en blanco como separador de bloques de datos. Quiero asegurarme de que la línea en blanco, y solo la línea en blanco, se deseche mientras leo los datos. También necesito que sea compatible y estándar.

Gracias por su ayuda.

Respuesta

3

Desde 2008 Fortran proyecto de norma:

Lista dirigida entrada/salida permite la edición de datos de acuerdo con el tipo del elemento de lista en lugar de por una especificación de formato. También permite que los datos sean de campo libre, es decir, separados por comas (o puntos y coma) o espacios en blanco .

Entonces:

Los caracteres en uno o más registros de la lista dirigida constituyen una secuencia de valores y separadores de valor . El final de un registro tiene el mismo efecto que un carácter en blanco, a menos que esté dentro de un carácter constante. Cualquier secuencia de dos o más espacios en blanco consecutivos se trata como un solo espacio en blanco, a menos que esté dentro de una constante de caracteres.

Unidos este implícitamente que en la entrada lista-dirigido, líneas en blanco se tratan como espacios en blanco hasta el siguiente valor no está en blanco.

Al usar un descriptor de formato fmt = '(A)' al leer, las líneas en blanco se leen en str. Por otro lado, fmt = *, que implica una E/S dirigida por listas en forma libre, omite las líneas en blanco hasta que encuentra una cadena de caracteres que no está en blanco. Para probar esto, hacer algo como:

PROGRAM chk_read 
INTEGER :: cnt 
INTEGER,   PARAMETER :: MAXLEN=30 
CHARACTER(len=MAXLEN)  :: str 

cnt=1 
do 
    read(*,fmt='(A)',end=100)str 
    write(*,'(I1,3A)')cnt,' str_start|', str, '|str_end' 
    cnt=cnt+1 
enddo 
100 continue 

END PROGRAM chk_read 

$ cat input.dat 



yamanakako 

kawaguchiko 

EOF

Ejecutar el programa da este resultado:

$ a.out < input.dat 
1 str_start|        |str_end 
2 str_start|        |str_end 
3 str_start|        |str_end 
4 str_start|yamanakako     |str_end 
5 str_start|        |str_end 
6 str_start|kawaguchiko     |str_end 

Por otro lado, si se utiliza de entrada por defecto:

read(*,fmt=*,end=100)str 

Usted termina con esta salida:

$ a.out < input.dat 
1 str1_start|yamanakako     |str1_end 
2 str2_start|kawaguchiko     |str2_end 
+0

Es una información muy útil que nunca se encontró con un caso excepcional sobre el comportamiento "fmt = *". Gracias. Apreciaría mucho, sin embargo, si pudiera confirmar que los comportamientos "fmt = *" y "fmt = '(A)'" que se observan aquí son los comportamientos estándar, por ejemplo, al citar alguna literatura. – norio

+0

@norio Acabo de editar mi respuesta con lo que podría estar buscando.Además, al escribir código portátil, es bueno tener acceso a diferentes plataformas: el estándar no garantiza el comportamiento, simplemente establece qué comportamiento debería ser. – milancurcic

+0

Gracias por la cita del borrador estándar. Eso es muy claro. Sí, estoy de acuerdo con usted acerca de la importancia de realizar pruebas en diferentes plataformas; al final, obtengo el resultado de una máquina real. Además de eso, en la fase inicial de redacción de un programa, quiero vigilar para no confiar en una peculiaridad de un entorno específico sin darme cuenta. – norio

2

esta parte del proyecto de norma F2008, probablemente, trata a su problema:

10.10.3 Lista dirigida entrada

7 Cuando el elemento reflexivo próxima e ff es de tipo carácter, la forma de entrada consiste en una secuencia posiblemente delimitada de 0 o más rep-char s cuyo tipo de parámetro de tipo está implícito en el tipo del elemento eficaz . Las secuencias de caracteres pueden continuar desde el final de un registro hasta el comienzo del siguiente registro, pero el final del registro no se producirá entre un apóstrofo duplicado en una secuencia de caracteres delimitada por apóstrofo , ni entre una cita doble en un secuencia de caracteres delimitada por comillas El final del registro hace no causa un espacio en blanco o cualquier otro carácter para formar parte de la secuencia de caracteres . La secuencia de caracteres puede continuarse en tantos registros como sea necesario.Los caracteres en blanco, coma, punto y coma y barra pueden aparecer en secuencias de caracteres predeterminadas, ASCII o ISO 10646.

+0

Gracias por la respuesta. La oración "El final del registro no causa que un espacio en blanco o cualquier otro carácter se convierta en parte de la secuencia de caracteres". podría estar relacionado con el comportamiento observado "fmt = *", pero no estoy seguro. ¿Tiene una URL para el borrador del estándar? – norio

+1

El borrador estándar de Fortran 2008 se encuentra en ftp://ftp.nag.co.uk/sc22wg5/N1801-N1850/N1826.pdf. Muchos otros documentos están en http://www.nag.co.uk/sc22wg5/. Creo que esa frase con la siguiente es lo que estás buscando. –

+0

gracias por los enlaces. Es un sitio muy útil. Por lo que yo entiendo, la oración "La secuencia de caracteres puede continuarse en tantos registros como sea necesario". significa que puedo pasar un archivo que tiene "kawaguchi \ nko" (por favor, interprete "\ n" como un carácter de nueva línea) para 'leer (*, *) str' para establecer el valor "kawaguchiko" en la variable 'str'. Por lo tanto, creo que esto es un poco diferente de lo que me preocupa. – norio

Cuestiones relacionadas