C++ streams confusion: iterador istreambuf vs iterador istream?


¿Cuál es la diferencia entre istreambuf_iterator y istream_iterator? Y en general, ¿cuál es la diferencia entre los arroyos y streambufs? Realmente no puedo encontrar ninguna explicación clara para esto, así que decidí preguntar aquí.

Author: Étienne, 2012-05-12

2 answers

Los IOstreams usan streambufs to como su fuente / destino de entrada / salida. Efectivamente, la familia streambuf hace todo el trabajo con respecto a IO y la familia IOstream solo se usa para formatear y transformar a-string / desde-string.

Ahora, istream_iterator toma un argumento de plantilla que dice cómo debe formatearse la secuencia de cadena sin formato del streambuf, como istream_iterator<int> interpretará (delimitado por espacios en blanco) todo el texto entrante como int s.

Por otra mano, istreambuf_iterator solo se preocupa por los caracteres crudos e itera directamente sobre el streambuf asociado del istream que se pasa.

Generalmente, si solo estás interesado en los caracteres crudos, usa un istreambuf_iterator. Si está interesado en la entrada formateada, utilice un istream_iterator.

Todo lo que dije también se aplica a ostream_iterator y ostreambuf_iterator.

 39
Author: Xeo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-12 13:28:12

Aquí hay un secreto realmente mal guardado: un iostream per se, no tiene casi nada que ver con leer o escribir desde/hacia un archivo en su computadora.

Un iostream básicamente actúa como un "casamentero" entre un streambuf y un local:

introduzca la descripción de la imagen aquí

El iostream almacena algún estado sobre cómo se deben realizar las conversiones (por ejemplo, el ancho actual y la precisión de una conversión). Los utiliza para dirigir la configuración regional cómo y dónde hacer una conversión (por ejemplo, convierta este número en una cadena en ese búfer con ancho 8 y precisión 5).

Aunque no preguntaste directamente sobre él, la configuración regional a su vez es realmente solo un contenedor but sino (por más bien una rareza) un contenedor heterogéneo seguro de tipo. Las cosas que contiene son facet s. Un objeto faceta define una sola faceta de una configuración regional general. El estándar define una serie de facetas para todo, desde la lectura y escritura de números (num_get, num_put) para clasificar caracteres (el ctype faceta).

De forma predeterminada, una secuencia utilizará la configuración regional "C". Esto es bastante básico numbers los números se convierten simplemente como un flujo de dígitos, las únicas cosas que reconoce como letras son las 26 minúsculas y las 26 mayúsculas en inglés, y así sucesivamente. Sin embargo, puede imbue una secuencia con una configuración regional diferente de su elección. Puede elegir locales para usar por nombres especificados en cadenas. Uno que es particularmente interesante es uno que está seleccionado por una cadena vacía. Usar una cadena vacía básicamente dice la biblioteca de tiempo de ejecución para seleccionar la configuración regional que "piensa" es la más adecuada, generalmente basada en cómo el usuario ha configurado el sistema operativo. Esto permite que el código maneje los datos en un formato localizado sin ser escrito explícitamente para ninguna configuración regional en particular.

Entonces, la diferencia básica entre un istream_iterator y un istreambuf_iterator es que los datos que salen de un istreambuf_iterator no han pasado por (la mayoría de las) transformaciones realizadas por la configuración regional, pero los datos que salen de un istream_iterator han sido transformado por la localización.

Por si sirve de algo, que "la mayoría de" en el párrafo anterior se refiere al hecho de que cuando se leen datos de un istreambuf (a través de un iterador o de otra manera) un poco de transformación basada en la localización es hecho: junto con varios tipos de "formateo" de cosas, la localización contiene una faceta codecvt, que es lo que se usa para convertir de una representación externa a una representación interna (por ejemplo, UTF-8 a UTF-32).

It puede tener más sentido ignorar el hecho de que ambos están almacenados en una configuración regional, y pensar solo en las facetas individuales involucradas:

introduzca la descripción de la imagen aquí

Así que esa es la diferencia real entre un istream_iterator y un istreambuf_iterator. Un poco de transformación se hace (al menos potencialmente) a los datos de cualquiera de los dos, pero sustancialmente menos se hace a los datos que provienen de un istreambuf_iterator.

 9
Author: Jerry Coffin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-25 04:21:11