2010-12-15 10 views
2

Disons que vous avez quelque chose comme:comment tronquer la largeur des types entiers avec std :: ostringstream?

std::ostringstream oss; 
int value(42); 
oss.fill('0'); 
oss << std::setw(3) << value; 
cout << oss.str(); 

SORTIE: 042

Cette sortie est parce que std :: setw assure une largeur minimale et nous a dit au cours d'eau pour remplir avec 0 mais comment voulez-vous faire le contraire et spécifier une largeur maximale de sorte que l'affichage sera tronquée en LIST et natif C++ de préférence ...

Actuellement j'ai quelque chose que je considère comme une bidouille horrible et inefficace:

std::ostringstream oss; 
int value(1239999); 
oss.fill('0'); 
oss << std::setw(3) << boost::lexical_cast<std::string, int>(value).substr(0, 3); 
cout << oss.str(); 

SORTIE: 123

Je l'ai regardé boost :: format mais c'est la même histoire là aussi loin que je peux dire qu'il n'y a aucun moyen de le faire « joli » ... des suggestions? MISE À JOUR: Les flux std :: ostringstream et STL en général sont connus pour fonctionner lentement par rapport aux autres conteneurs et objets de modèle STL. Peut-être que je ferais mieux de créer un objet de file d'attente de messages qui enveloppe et utilise en interne une std :: queue, puis utilise simplement sprintf_s à des fins de formatage?

+0

Comment diable peut-il être correct que '" 123 "' est une représentation correcte de '123' et' 1239999'? Si c'est vrai, je ne pense pas que vous ayez vraiment des entiers. – SingleNegationElimination

+0

Ceci est une simple représentation hors contexte pour clarifier le problème ... en utilisation réelle la valeur représente les secondes fractionnaires d'un objet temps posix enregistré dans le cadre d'un horodatage pour l'entrée qui est inexact après 3 chiffres sur la plupart des systèmes d'exploitation , gaspille de l'espace et rend le journal plus difficile à lire. – AJG85

Répondre

0

Les fonctionnalités de mise en forme de flux ne sont pas conçues comme un package de manipulation de chaînes à usage général. Ce que vous essayez de faire n'a pas beaucoup de sens numériquement, donc il n'est pas supporté - l'utilisation de la sous-chaîne ou de fonctions similaires est la voie à suivre. Vous pouvez (et devriez, si vous en avez besoin dans plus d'un endroit) écrire votre propre fonction pour faire le travail.

Quelque chose comme:

#include <iostream> 
#include <sstream> 
#include <string> 
#include <iomanip> 

void First3(std::ostream & os, int value) { 
    std::ostringstream oss; 
    oss.fill('0'); 
    oss << std::setw(3) << value; 
    os << oss.str().substr(0, 3); 
} 

int main() { 
    First3(std::cout, 1239999); 
    std::cout << " "; 
    First3(std::cout, 1); 
} 

Notez qu'il n'y a pas besoin de Boost à utiliser.

+0

c'est purement pour le formatage d'affichage des fractions de secondes dans une bibliothèque de journalisation. Il est seulement utilisé dans un endroit mais cet endroit est utilisé fortement, c'est pourquoi je suis préoccupé par la performance du hack proposé, bien que cela ne s'est pas encore avéré problématique. boost est déjà largement utilisé dans nos applications et dans ce cas, itoa n'est pas supporté sur toutes les plateformes donc c'est mieux. – AJG85

3

Tronquer pour supprimer des chiffres significatifs est "désapprouvé" par la plupart des programmeurs modernes. Dans les mauvais jours de mise en forme FORTRAN, il était assez courant pour obtenir une sortie comme

Total Sales 
----------- 
9,314,832.36 
1,700,328.04 
*,***,***,** 
8,314,159.26 
... 

Excel jour même moderne tombe dans ce piège avec son indication de débordement de la largeur du champ de ########

Si le nombre étant sortie ne ne correspond pas à la largeur du champ, la philosophie actuelle est de briser les limites de la largeur du champ et de montrer de manière fiable la valeur. Le seul inconvénient serait si un programme FORTRAN va lire l'entrée (s'attendant ainsi à une utilisation stricte des colonnes).

+0

Nous avions l'habitude d'avoir ce problème avec COBOL: passer une valeur à travers une chaîne de programmes, ne pas avoir assez de 9 dans le '9 (x) V99' dans un programme, obtenir une mauvaise valeur plausible. –

+0

La troncature est parce que le temps de posix que j'utilise pour la bibliothèque de journalisation met des secondes fractionnaires à plus de 6 chiffres lorsque les fenêtres et la plupart de l'horloge OS est seulement précise au 1/60e de seconde ou environ 3 chiffres ... espace dans le journal. – AJG85

+0

Si le but est simplement d'éliminer l'excès de précision, alors supprimez arithmétiquement les chiffres supplémentaires en multipliant par une puissance de dix, tronquant à un entier et divisant par la même puissance de dix. Il y a une chance que cela ne fonctionne pas en raison de la précision réduite en virgule flottante, mais la méthode de troncature de chaîne fonctionnera efficacement tant que l'ampleur du nombre est connue. – wallyk

Questions connexes