2011-03-31 15 views
7

Al tratar de llegar a una respuesta a this question, escribí esta pequeña prueba-programa:¿Está bien usar iostreams con int como character-type?

#include <iostream> 
#include <fstream> 
#include <vector> 
#include <iterator> 
#include <algorithm> 

void writeFile() { 
    int data[] = {0,1,2,3,4,5,6,7,8,9,1000}; 

    std::basic_ofstream<int> file("test.data", std::ios::binary); 
    std::copy(data, data+11, std::ostreambuf_iterator<int>(file)); 
} 

void readFile() { 
    std::basic_ifstream<int> file("test.data", std::ios::binary); 
    std::vector<int> data(std::istreambuf_iterator<int>(file), 
     (std::istreambuf_iterator<int>())); 

    std::copy(data.begin(), data.end(), 
       std::ostream_iterator<int>(std::cout, " ")); 
    std::cout << std::endl; 
} 


int main() 
{ 
    writeFile(); 
    readFile(); 

    return 0; 
} 

Funciona como se esperaba, la escritura de los datos en el archivo, y después de leer el archivo, se imprime correctamente:

0 1 2 3 4 5 6 7 8 9 1000 

sin embargo, no estoy seguro de si hay trampas (cuestiones endianess un lado, que siempre tienen estos cuando se trata de datos binarios)? Está permitido?

Respuesta

2

La instanciación de cualquiera de las clases iostream, o basic_string, en cualquier cosa pero char o wchar_t, sin proporcionar una clase específica de rasgos personalizados, es un comportamiento indefinido; la mayoría de las bibliotecas que he visto lo definen a hacen algo, pero esa definición a menudo no está especificada, y es diferente entre VC++ y g ++ (los dos casos que he analizado). Si define y usa su propia clase de rasgos, algunas de las funciones deberían funcionar en .

Para casi todos los dispositivos de inserción formateados y extractores (los << y >> operadores), y istreamostream delegado a diversas facetas en la configuración regional; si se utiliza alguno de estos, deberá seguir los pasos indicados en para asegurarse de que estos funcionen también. (Esto generalmente significa proporcionar una nueva faceta numpunct.)

Incluso si sólo se utiliza el streambuf (como en el ejemplo), filebuf utiliza la faceta codecvt. Y no se requiere una implementación para proporcionar un codecvt, y si lo hace, puede hacer prácticamente lo que quiera en . Y dado que filebuf siempre escribe y lee char ay desde el archivo , esta traducción debe hacer algo. De hecho, estoy bastante sorprendido de que el código haya funcionado, , debido a esto. Pero todavía no sabe lo que estaba realmente en el disco, lo que significa que no puede documentarlo, lo que significa que no podrá leerlo en el futuro.

Si su objetivo es escribir datos binarios, su primer paso debe ser definir el formato binario, luego escribir las funciones de lectura y escritura que implementar.Posiblemente usando el iostream < < y >> sintaxis, y probablemente usando un basic_streambuf<char> para la entrada real y salida ; a basic_streambuf<char> que ha imbuido con la configuración local "C" . O en lugar de definir su propio formato binario, simplemente use un existente, como XDR. (Todo este párrafo supone que desea guardar los datos, y leerlos más tarde. Si estos son solo archivos temporales, para derramar datos internos temporales en el disco durante una sola ejecución, y se eliminarán al final de la ejecución del programa, soluciones más simples son válidas.)

4

Funciona como se esperaba.

No estoy seguro de lo que se esperaba ...

sólo es permitido?

Probablemente no sea portátil. Streams se basa en char_traits y en las facetas que se definen en el estándar solo para char y wchar_t. Una implementación puede proporcionar más, pero mi apuesta sería confiar en una implementación predeterminada mínima de esas plantillas y no en una implementación consciente para int. No me sorprendería que un uso más profundo llevaría a problemas.

+0

Hm, eso confirma mi sospecha. –

+0

Eso significa que si realmente lo quiero, podría especializar 'char_traits' para' int'. –

+0

+1, aunque creo que es bastante obvio lo que se espera. –

Cuestiones relacionadas