web-dev-qa-db-fra.com

Conversion double en tableau de caractères C++

J'essaye de convertir (et arrondir) un double en tableau de caractères sans convertir avec un std :: to_string sur le double en premier. Cependant, je reçois un texte de mémoire aléatoire à la place. Qu'est-ce que je fais mal? 

Voici mon code:

double d = 1.0929998; 
d = std::round(d * 100) / 100;

char s[sizeof(d)];
std::memcpy(s,&d,sizeof(d));

Résultat:

s: q = × £ pñ?

Valeur prévue: 

s: 1.09

6
Delrog

Vous traduisez les octets littéraux de votre double en chars. La valeur double est une représentation binaire (généralement quelque chose comme IEEE 754 ), tandis que char est une représentation binaire d’un caractère (généralement quelque chose basé sur ASCII ). Ces deux ne sont pas compatibles.

Malheureusement, cela signifie que vous devez suivre un processus de conversion. Soit la std::to_string() que vous avez dit ne pas vouloir faire, soit un std::stringbuf plus compliqué (qui appellera quand même std::to_string() sous le capot)

6
tdk001

Vous copiez une double (qui est une représentation binaire d'un nombre) dans un tableau char; il n'y a aucune raison pour que ces octets correspondent aux caractères numériques.

3
Scott Hunter

Si vous voulez convertir manuellement sans utiliser to_string, vous devrez extraire les chiffres un à un. Un double n'est pas stocké en mémoire sous forme de jeu de caractères. Vous ne pouvez donc pas simplement copier la mémoire en espérant que tout fonctionne. (pour plus d'informations sur l'interprétation des doubles, voir ici ).

1
scohe001

Juste fais ceci premier:

std::ostringstream strs;
strs << dbl;
std::string str = strs.str();

Ceci convertit une double dbl en une chaîne str.

Ensuite, vous pouvez le convertir en un tableau de caractères comme celui-ci:

char *cstr = new char[str.length()+1];
str.copy(cstr, str.length());
cstr[str.length()] = '\0';
// use cstr as needed...
delete[] cstr;

Ou simplement ceci:

const char *cstr = str.c_str();
// use cstr as needed...
1
Seba D'Agostino

Ceci n’a pas été testé mais vous pouvez essayer:

std::string to_string(double x)
{
    std::ostringstream ss;
    ss << x;
    return ss.str();
}

Vous pouvez ensuite mettre les caractères de la chaîne retournée dans un tableau de caractères comme ceci:

std::string str = to_string(doubleValue);
char digits[str.length()];

Et puis, grâce au commentaire de Rémy Lebeau, vous pouvez faire ceci:

std::strncpy(digits, to_string(doubleValue).c_str(), sizeof(digits))

ou ca:

to_string(doubleValue).copy(digits, sizeof(digits))
1
LAD

Le processus de conversion par vous-même sans utiliser to_string peut être le suivant:

char* to_char_array(double num_double, int decimal_place)
{
    int num_int = std::round(num_double * pow(10, decimal_place));
    int sign = num_int < 0 ? 1 : 0;
    num_int = abs(num_int);

    if (num_int == 0)
    {
        char* s = (char*)malloc(decimal_place + 3);
        s[0] = '0';
        s[1] = '.';
        for (int i = 2; i < decimal_place + 2; i++)
            s[i] = '0';
        s[decimal_place + 2] = '\0';
        return s;
    }

    int digit_count = 1;
    int n = num_int;
    if (n >= 100000000) { digit_count += 8; n /= 100000000; }
    if (n >= 10000) { digit_count += 4; n /= 10000; }
    if (n >= 100) { digit_count += 2; n /= 100; }
    if (n >= 10) { digit_count++; }

    int size = digit_count + 1 + (decimal_place > 0 ? 1 : 0) + sign;
    char* s = (char*)malloc(size);

    for (int i = 0, integer = num_int; integer != 0; integer /= 10) {
        s[size - 2 - i++] = integer % 10 + 48;
        if (decimal_place > 0 && i == decimal_place)
            s[size - 2 - i++] = '.';
    }
    s[size - 1] = '\0';
    if (sign)
        s[0] = '-';
    return s;
}

void main()
{
    double d = -12.268904;
    char* s = to_char_array(d, 3);
    cout << "double: " << d << " - char array: " << s << endl;
    system("pause");
}
1
Hossein Golshani