1
votes

Utilisation de C ++, problème de conversion d'un int en caractère ayant toujours 3 chiffres

J'essaie de convertir un entier avec une valeur de 1-360 et de l'enregistrer en tant que caractère de valeur 001-360 . Exemples 1 = 001 , 43 = 043 , 349 = 349 . (S'il y a une meilleure approche que char, je suis toute oreille)

J'ai recherché différentes approches météo en utilisant string ou char [] mais je n'arrive pas à faire les choses correctement.

LOtrackAngle va être un nombre entier 1-360

LOtrackAngle=7, Output is 16100719.

Est:

LOtrackAngle=248, Output is 16124819.
LOtrackAngle=34, Output is 1613419.
LOtrackAngle=7, Output is 161719.

Doit être:

case 'q':
case 'Q':
{
    char trackAngleCHR[4];
    sprintf(trackAngleCHR, "%d", LOtrackAngle);
    ss << " 16"
       << "1" << trackAngleCHR << ""
       << "1"
       << "9";
    LOtrackAngle += 1;
    if (LOtrackAngle > 360)
    {
        LOtrackAngle = LOtrackAngle - 360;
    }
    break;
}

J'ai besoin que ceux-ci contiennent toujours 8 caractères.


3 commentaires

sprintf (trackAngleCHR, "% d", LOtrackAngle); -> sprintf (trackAngleCHR, "% 03d", LOtrackAngle); , comme décrit dans documentation ?


Ce sprintf est une recette pour un buffer overflow contre un char [4] . Utilisez simplement ostream après avoir défini la largeur, l'alignement et le remplissage appropriés.


@ AlgirdasPreidžius C'est une très bonne réponse que vous avez là-bas, pourquoi ne pas la poster?


3 Réponses :


4
votes

Puisque vous utilisez déjà des flux, je vous recommande d'utiliser des solutions entièrement C ++:

#include <iomanip> //for std::setw

case 'q':
case 'Q':
{
    ss << " 16" << "1" 
       << std::setw(3) << std::setfill('0') << LOtrackAngle
       << "1" << "9";

    LOtrackAngle += 1;
    if (LOtrackAngle > 360)
    {
        LOtrackAngle = LOtrackAngle - 360;
    }
    break;
}

Ce n'est pas seulement plus concis et plus facile à lire, mais aussi sûr contre le débordement de tampon (au cas où votre numéro ne rentrera pas dans le tampon de longueur 4 pour une raison quelconque, vous n'obtiendrez pas un UB étrange)


2 commentaires

Merci Yksisarvinen. quand je l'ai exécuté dans mon code, il a laissé un espace de 1 ou 2 caractères dans le flux au lieu d'ajouter des 0. Je devrai me souvenir de setw () pour de futurs problèmes.


@ROVguy Vous avez raison, j'ai oublié de changer le caractère de remplissage. Cela devrait fonctionner maintenant.



0
votes

Jetez un œil à ceci:

int main()
{
    int number = 360;
    char chars[4];
    auto str = std::to_string(number);
    str.insert(0, 3 - str.size(), '0');
    std::memcpy(chars,str.data(),str.size());

    return 0;
}

En utilisant cette méthode, vous pouvez soit conserver la chaîne d'origine, soit la mémoriser dans un caractère [].

EDIT: Ajouté une doublure pour insérer des 0 si nécessaire.


2 commentaires

Merci Alex. J'ai utilisé votre correctif car il ajoute des 0 là où il n'y a pas de chiffres et utilise des flux dans la solution. Je vais devoir lire sur l'auto!


@ROVguy Pas de problème. N'oubliez pas d'accepter une réponse comme étant la bonne, afin que les personnes ayant le même problème que vous puissent trouver la solution plus rapidement.



0
votes

Voici une alternative qui n'utilise pas de chaînes ou de flux supplémentaires.

038
001
534

Sortie :

#include <cstring>
#include <iostream>

char* fill_char_array(char *arr, int size, int num)
{
    if ( size <= 0 )
       return arr;
    memset(arr, '0', size);  // set all positions to character 0
    arr[size-1] = 0;  // null terminate
    int index = size - 2;
    while (num > 0 && index >= 0)
    {
       arr[index] = (num % 10) + '0';  // set the digit in the array
       num /= 10;
       --index;
    }
    return arr;
}

int main()
{
    char trackAngleCHR[4];
    std::cout << fill_char_array(trackAngleCHR, 4, 38) << "\n";
    std::cout << fill_char_array(trackAngleCHR, 4, 1) << "\n";
    std::cout << fill_char_array(trackAngleCHR, 4, 534) << "\n";
}


0 commentaires