2012-09-11 17 views
6

Estoy usando la configuración regional rusa en mi PC.
Si hubiera establecido:¿std :: locale :: global afecta a la función printf()?

class numpunct_withpoint: public numpunct<char> 
{ 
protected: 
    /// Override the function that gives the decimal separator. 
    char do_decimal_point() const 
    { 
     return '.'; 
    } 
}; 
... 
locale loc(std::locale::classic(), new numpunct_withpoint); 
std::locale::global(loc); 


y que

printf("%f", 3.14); 

salida es:

3,14 

separador decimal es "" no como en función de do_decimal_point ! ¿Cómo puedo cambiar la configuración regional de C para el separador decimal con la configuración regional C++?


Thanks for answer!
Pero, ¿la función de C setlocale afecta al objeto C++ cout?

setlocale(LC_NUMERIC, "C"); 

afectaría esta marca al imprimir valor decimal a través cout?

Respuesta

0

La biblioteca C no utiliza la misma configuración regional que C++. Para anular la configuración regional utilizado por printf, utilice setlocale:

setlocale(LC_NUMERIC, "POSIX"); 

o similar.

+0

Sin embargo, la configuración regional :: función 'global' * * se llame' setlocale' para usted, si se le pasa un local llamado . –

5

Cuando establece la configuración regional global de C++ también se modifica la configuración regional C. Si modifica la configuración regional C, la configuración regional global de C++ no está modificada.

A continuación se muestra la configuración de la configuración regional global de C++.

#include <cstdio> 
#include <clocale> 
#include <fstream> 

int main() { 
    const char * locale_name = "French_France.1252"; // or "fr_Fr.UTF-8" on Unix 
    double value = 1.2; 

    std::locale::global(std::locale(locale_name)); 

    std::ofstream("out.txt") << "C++ " << value << '\n'; 

    if (FILE *f = std::fopen("out.txt", "a")) { 
     std::fprintf(f, "C %1.1e\n", value); 
     std::fclose(f); 
    } 
} 

Tanto la salida C como la salida C++ deben usar un coma decimal.

C++ 1,2
C 1,2e + 000

Si reemplaza el establecimiento de la configuración regional de C++ con la configuración de la configuración regional C, std::setlocale(LC_ALL, locale_name);, la salida debe cambiar para que sólo la salida C usa una coma decimal mientras que la salida de C++ sigue usando el símbolo decimal del período predeterminado.

C++ 1.2
C 1,2e + 000

Sin embargo, el hecho de que el establecimiento de la configuración regional C++ afecta a la configuración regional C no hace localidades C extensible en la forma en que C lugares ++ son. Las funciones basadas en la configuración regional de C nunca usarán las facetas personalizadas de C++. En su lugar, debe confiar en que su sistema admite una configuración regional con nombre que tenga la funcionalidad que necesita.

Específicamente, std::locale::global() se define para establecer la configuración regional C utilizando el nombre de la configuración regional C++ que elija, si tiene un nombre. El comportamiento es la implementación definida si la configuración regional de C++ no tiene un nombre.Además, C++ especifica que la combinación de dos lugares con nombre produce una configuración regional con nombre. Algunas implementaciones producen nombres combinados útiles que le permiten mezclar C categoría de localizaciones, basta con situar el C++ local:

std::locale::global(std::locale(std::locale("ru_RU"), "C", std::locale::numeric)); 

Con libstdC++ esto produce un local llamado:

LC_CTYPE = es_ES; LC_NUMERIC = C; LC_TIME = es_ES; LC_COLLATE = es_ES; LC_MONETARY = es_ES; LC_MESSAGES = es_ES; LC_PAPER = es_ES; LC_NAME = es_ES; LC_ADDRESS = es_ES; LC_TELEPHONE = es_ES; LC_MEASUREMENT = es_ES; LC_IDENTIFICATION = es_ES LC_CTYPE = es_ES; LC_NUMERIC = C; LC_TIME = es_ES ; LC_COLLATE = ru_RU; LC_MONETARY = ru_RU; LC_MESSAGES = ru_RU; LC_PAPER = ru_RU; LC_NAME = ru_RU; LC_ADDRESS = ru_RU; LC_TELEPHONE = ru_RU; LC_MEASUREMENT = ru_RU; LC_IDENTIFICATION = r u_RU

Para que la configuración regional C se establezca en la misma mezcla entre las configuraciones regionales "ru_RU" y "C" que la configuración regional C++.

Desafortunadamente, otras implementaciones eligen un comportamiento menos útil, aunque técnicamente conforme. En Visual Studio

std::locale::global(std::locale(std::locale("Russian_Russia.1251"), "C", std::locale::numeric)); 

produce una configuración regional con el nombre "C". Por lo tanto, si bien la configuración regional de C++ es la combinación adecuada de las categorías locales R y C, la configuración regional C simplemente se establece en "C". Así que en estas plataformas para mezclar C categorías del local debe establecer directamente la configuración regional C:

// set the C++ locale first 
std::locale::global(std::locale(std::locale("Russian_Russia.1251"), "C", std::locale::numeric)); 

// set the C locale second, because it will not overwrite the changes you made to the C++ locale 
std::setlocale(LC_ALL, "Russian_Russia.1251"); 
std::setlocale(LC_NUMERIC, "C"); 
Cuestiones relacionadas