2010-12-15 11 views
2

Angenommen, Sie haben so etwas wie:wie die Breite von ganzzahligen Typen mit std :: ostringstream abgeschnitten wird?

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

OUTPUT: 042

Dieser Ausgang ist da std :: setw eine Mindestbreite gewährleistet, und wir sagten, den Strom mit 0 zu füllen aber wie macht man das Gegenteil und geben Sie eine maximale Breite, so dass Anzeige in AWL und native C++ vorzugsweise abgeschnitten ...

Zur Zeit habe ich etwas, das ich einen hässlichen und ineffizient Hack betrachten:

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(); 

OUTPUT: 123

ich boost :: Format geschaut haben, aber es ist es die gleiche Geschichte, soweit ich keine Möglichkeit, es sagen kann, ist diese „hübsch“ zu tun ... irgendwelche Vorschläge?

UPDATE: std :: ostringstream und STL-Streams im Allgemeinen sind bekannt, langsam im Vergleich zu anderen Containern und Vorlagenobjekte von STL durchzuführen. Vielleicht wäre es besser, ein Nachrichtenwarteschlangenobjekt zu erstellen, das eine std :: -Warteschlange umschließt und intern verwendet und dann einfach sprintf_s für Formatierungszwecke verwendet?

+0

Wie kann es richtig sein, dass '" 123 "' eine korrekte Darstellung von '123' und' 1239999' ist? Wenn das wahr ist, glaube ich nicht, dass Sie wirklich Ganzzahlen haben. – SingleNegationElimination

+0

Dies ist eine einfache Darstellung außerhalb des Kontexts, um das Problem zu verdeutlichen ... In der tatsächlichen Verwendung repräsentiert der Wert Bruchteile Sekunden eines Posix-Zeitobjekts, das als Teil eines Zeitstempels für den Eintrag protokolliert wird, der bei den meisten Betriebssystemen hinter den 3 Ziffern ungenau ist , verschwendet Speicherplatz und erschwert das Lesen des Protokolls. – AJG85

Antwort

0

Die Stream-Formatierungsfunktionen sind nicht als allgemeines Paket zur Zeichenfolgenbearbeitung gedacht. Was du versuchst zu tun, macht nicht viel Sinn, daher wird es nicht unterstützt - die Verwendung der Teilzeichenfolge oder ähnlicher Funktionen ist der richtige Weg. Sie können (und sollten, wenn Sie dies an mehr als einem Ort benötigen) eine eigene Funktion schreiben, um den Job zu erledigen.

Etwas wie:

#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); 
} 

Hinweis gibt es keine Notwendigkeit für Boost-verwendet werden soll.

+0

Es dient nur zur Formatierung von Sekundenbruchteilen in einer Protokollierungsbibliothek. Es wird nur an einem Ort verwendet, aber dieser Ort wird stark genutzt, weshalb ich über die Leistung des vorgeschlagenen Hacks besorgt bin, obwohl es sich bisher nicht als problematisch erwiesen hat. Boost ist in unseren Apps bereits weit verbreitet und in diesem Fall wird itoa nicht auf allen Plattformen unterstützt, daher ist dies besser. – AJG85

3

Abschneiden, um signifikante Ziffern zu entfernen, wird von den meisten modernen Programmierern "verpönt". In den schlechten alten Tagen der Fortran-Formatierung, war es ziemlich häufig eine Ausgabe wie

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

Auch Excel in diese Falle der mit seiner Feldbreite Überlaufanzeige ########

fällt moderne zu bekommen Wenn die Zahl ausgegeben tut Nicht in die Feldbreite passen, ist die aktuelle Philosophie, die Grenzen der Feldbreite zu brechen und den Wert zuverlässig zu zeigen. Der einzige Nachteil wäre, wenn ein FORTRAN-Programm die Eingabe lesen würde (also eine strenge Spaltenbenutzung erwartet).

+0

Wir hatten dieses Problem mit COBOL: einen Wert durch eine Kette von Programmen übergeben, nicht genügend 9s in der '9 (x) V99' in einem Programm haben, einen plausibel aussehenden schlechten Wert bekommen. –

+0

Die Verkürzung ist, weil die posix Zeit, die ich für die Protokollierungsbibliothek verwende, Bruchteilssekunden auf 6+ Stellen herausstellt, wenn Windows und die meisten OS-Uhr nur auf 1/60 einer Sekunde oder ungefähr 3 Ziffern genau ist ... es spart auch Platz im Protokoll. – AJG85

+0

Wenn das Ziel einfach darin besteht, überschüssige Genauigkeit zu entfernen, dann entfernen Sie arithmetisch die zusätzlichen Ziffern, indem Sie mit einer Zehnerpotenz multiplizieren und auf eine ganze Zahl abschneiden und durch die gleiche Zehnerpotenz dividieren. Es gibt eine Chance, die aufgrund von Gleitkomma-reduzierter Genauigkeit möglicherweise nicht funktioniert, aber die Methode zum Verkürzen der Zeichenfolge funktioniert, solange die Größe der Zahl bekannt ist. – wallyk