2011-07-14 17 views
6

La especificación para strtol conceptualmente divide la cadena de entrada en "espacios en blanco iniciales", una "secuencia de asunto" y una "cadena final", y define la "secuencia de asunto" como:Lenguaje confuso en la especificación de strtol, et al

la subsecuencia inicial más larga de la cadena de entrada, comenzando con el primer carácter de espacio no blanco que es de la forma esperada. La secuencia del asunto no contendrá ningún carácter si la cadena de entrada está vacía o si está formada exclusivamente por espacios en blanco, o si el primer carácter que no es de espacio en blanco es distinto de un signo o una letra o dígito permitidos.

En un momento me pareció que el negocio "más larga subsecuencia inicial" era similar a la forma en que funciona scanf, donde "[email protected]" escanearían como "0x", un partido fallido, seguido por "@" como el siguiente carácter no leído. Sin embargo, después de un debate, estoy mayormente convencido de que strtol procesa la subsecuencia inicial más larga que es de la forma esperada, no la cadena inicial más larga que es la subsecuencia inicial de alguna cadena posible de la forma esperada.

Lo que todavía me confunde es el lenguaje de la memoria:

Si la secuencia sujeto está vacío o no tiene la forma esperada, no se realiza ninguna conversión; el valor de str se almacena en el objeto apuntado por endptr, siempre que endptr no sea un puntero nulo.

Si aceptamos lo que parece ser la correcta definición de "secuencia sujeto", no hay tal cosa como una secuencia sujeto que no esté vacía que no tiene la forma esperada, y en su lugar (para evitar la redundancia y confusión) el texto debería simplemente leer:

Si la secuencia de asunto está vacía, no se realiza ninguna conversión; el valor de str se almacena en el objeto apuntado por endptr, siempre que endptr no sea un puntero nulo.

¿Alguien puede aclarar estos problemas para mí? Tal vez sería útil un enlace a discusiones pasadas o cualquier informe de defectos relevante.

+1

Y un ejemplo normativo simple habría aclarado todo ... –

+1

De hecho. Tengo la sensación de que el comité en realidad estaba tratando de evitar ser explícito por temor a abrir un argumento sobre cómo debería comportarse ... –

Respuesta

1

El POSIX spec for strtol parece ser más claro:

Estas funciones serán convertir la porción inicial de la cadena apuntada por str a una larga y larga representación de tipo largo, respectivamente. En primer lugar, se descomponen la cadena de entrada en tres partes:

  1. una inicial, posiblemente vacío, secuencia de caracteres de espacio en blanco (según lo especificado por isspace())

  2. una secuencia sujeto interpreta como un número entero representado en alguna raíz determinada por el valor de base

  3. Una cadena final de uno o más caracteres no reconocidos, incluido el carácter NUL de terminación de la cadena de entrada.

Luego intentarán convertir la secuencia del asunto a un número entero, y devolverán el resultado.

Pero, por supuesto, no es normativo y "se remite al estándar ISO C".

+0

Estaba leyendo la versión POSIX de la especificación de todos modos. :-) –

+0

¿Qué revisión de POSIX? Quizás aclararon la redacción? – Nemo

+0

2008, el mismo que enlazó. –

3

creo que el lenguaje C99 es bastante claro:

La secuencia en cuestión se define como la subsecuencia inicial más largo de la cadena de entrada, empezando por el primer carácter que no sea un espacio en blanco, que es de la forma esperada

Dado "[email protected]", "[email protected]" no es de la forma esperada; "0x" no es de la forma esperada; por lo tanto, "0" es la subsecuencia inicial más larga que tiene la forma esperada.

Estoy de acuerdo que esto implica que no se puede tener una secuencia sujeto que no esté vacía que no es de la forma esperada - a menos que interpretar lo siguiente:

En distinto del "C" local, locale- adicional sujeto específico formularios de secuencia pueden ser aceptados.

... como permitir que una configuración regional defina otras formas posibles que podría tener la secuencia de asunto, que sin embargo no son de "la forma esperada".

La redacción en el párrafo final parece ser solo "correas y llaves".

+0

Me interesa su opinión. uno podría evitar el requisito con la cláusula loca .. :-) –

2

Podría ser más fácil de entender si usted comenzó a §7.20.1.4 (El strtol, strtoll, strtoul y funciones strtoull) ¶2 de la norma C99, en lugar de ¶4:

¶2 Las funciones strtol, strtoll, strtoul y strtoull convierten la parte inicial de de la cadena apuntada por nptr a int largo, int largo largo, 0 sin firmar int largo, y la representación int largo largo sin signo, respectivamente. Primero, descomponen la cadena de entrada en tres partes: una secuencia inicial, posiblemente vacía, de caracteres de espacio en blanco (especificados por la función isspace), una secuencia de asunto que se asemeja a un número entero representado en algún radix determinado por el valor de base, y una cadena final de uno o más caracteres no reconocidos, incluido el carácter nulo de terminación de la cadena de entrada. Luego, intentan convertir la secuencia del asunto a un entero y devuelven el resultado.

¶3 Si el valor de base es cero, la forma esperada de la secuencia objeto es el de una constante entera como se describe en 6.4.4.1, opcionalmente precedido por un signo más o menos, pero no incluyendo un número entero sufijo. Si el valor de base está entre 2 y 36 (inclusive), la forma esperada de la secuencia sujeto es una secuencia de letras y dígitos que representa un entero con el radix especificado por base, opcionalmente precedido por un signo más o menos, pero sin incluir un sufijo entero. Las letras de a (o A) a z (o Z) son con los valores 10 a 35; solo se permiten letras y dígitos cuyos valores atribuidos son menores a que los de base. Si el valor de base es 16, los caracteres 0x o 0X pueden opcionalmente preceden a la secuencia de letras y dígitos, siguiendo el signo si está presente.

¶ 4. La secuencia en cuestión se define como la subsecuencia inicial más largo de la cadena de entrada, ...

En particular, ¶3 aclara lo que es una secuencia sujeto.

1

Estoy totalmente de acuerdo con su evaluación: por definición, todas las secuencias de temas no vacíos son de forma esperada, por lo que la redacción de la norma es dudosa.

En el caso de las funciones de conversión de punto flotante, hay otro error (C99: sección TC3 7.20.1.3, § 3):

[...] La secuencia sujeto se define como la más larga inicial subsecuencia de la cadena de entrada, comenzando con el primer carácter de espacio no blanco , que es de la forma esperada. La secuencia del asunto no contiene caracteres si la cadena de entrada no es del formato esperado .

Esto implica que la cadena de entrada entera debe ser de la forma esperada, derrotando el propósito del parámetro endptr. Se podría argumentar que la forma esperada para la cadena de entrada es diferente de la forma esperada para la secuencia del tema, pero sigue siendo bastante confusa.

También son correctas que la semántica de la familia de funciones strto*() y *scanf() son diferentes: Si tanto partido, que siempre estarán de acuerdo en el valor y consumir el mismo número de caracteres (y cualquier Implementación libc en los que no hacen es roto, incluyendo newlib y glibc la última vez que lo verifiqué), pero *scanf() tampoco coincide con los casos en los que necesitaría dar marcha atrás a más de un carácter, como en los ejemplos "[email protected]" y "1.0e+".

Cuestiones relacionadas