Ausrichtung mit setw und right

BLR

Erfahrenes Mitglied
Hallo zusammen :)

ich muss einen Betrag rechts-bündig ausgeben lassen.
Die einzelnen Ziffer habe ich im vector<char>
Es kann höhstens bis 999Mln. gehen: 999.999.999
Also hätte ich maximal 11 Stellen.
So schreibe ich folgendes:

Code:
cout << setw(11) << right; //Für nächste Ausgabe lege ich fest: 
                                                      //Anzahl von Stellen: 11, Ausrichtung: rechts
for (int i = formatedValue.size(); i > 0; i--) {
      cout << values.at(i - 1);
}
Komischeweise gibt er mir die zahlen genau linksbündig aus.
Der Inhalt vom values ist bsp: 23.000

Danke für jeden Tipp
 
Hallo

ich muss einen Betrag rechts-bündig ausgeben lassen.
Die einzelnen Ziffer habe ich im vector<char>
Es kann höhstens bis 999Mln. gehen: 999.999.999
Ich sage es mal vorsichtig: Das ist ein äusserst ungünstiger Ansatz. Selbst ein signed int geht bis zu 2.147.483.647, was deinen Wert überschreitet und dabei erst noch nur 4 Bytes im Vergleich zu den 11 Bytes des char-Arrays benötigt. Zudem ergeben sich dadurch die Probleme, die gerade erfährst.
Ein std::cout << int(value) << endl; würde exakt das tun, was du willst.
Erklärung: std::cout berücksichtigt Rechtsbündigkeit schon, aber bei einzelnen Zeichen fällt das nicht auf. Das jeweils nächste Zeichen wird rechts davon angehängt -> es sieht nicht rechtsbündig aus.

Nun gibt es 2 Möglichkeiten:
a) Du schreibst dir eine eigene Rechtsbündigkeitsfunktion. Das heisst: Jedes Zeichen gehört an die Position (offset - (Länge der Zeichenkette) + (Position des Iterators in der Zeichenkette)). (ungetestet)
b) Du machst dir std::string zunutze, indem du an die Zeichenkette ein 0 anhängst und den Vector dann in den Copy-Constructor einer std::string-Instanz einsetzt.
//EDIT: Den std::string brauchst du nicht einmal. cout << formatedValue.data() << endl; tut's auch und ist ein bisschen leichtgewichtiger.
Dazu habe ich einen Code geschrieben, der funktioniert. Falls du also mit den obigen Erläuterungen nicht weiterkommst:
C++:
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <deque>
#include <time.h>
#include <algorithm>
#include <iterator>
#include <iostream>
#include <iomanip>

int main(int argc, char* argv[])
{
    srand(time(NULL));
    for (size_t c = 0; c < 10; c++)
    {
        std::cout << std::setw(11) << std::right;
        std::vector<char> formatedValue;
        for (size_t s = 0; s < 1 + rand() % 10; s++)
        {
            formatedValue.push_back(48 + (1 + rand() % 9));
        }
        formatedValue.push_back(0);
        /*std::string str(formatedValue.data());
        std::cout << str.c_str();*/ //Unnötig, da:
        std::cout << formatedValue.data(); //... es auch tut
        std::cout << std::endl;
    }
    system("PAUSE");
    return 0;
}

Gruss
cwriter
 
Zuletzt bearbeitet:
Vielen Dank für die Hilfe.
Leider funktioniert das nicht....
mit:

C++:
string str(formatedValue.data());
        cout << setw(11) << right;
        cout << str.c_str();

Funktioniert das nicht, er richtet mir das nicht nach rechts aus und er gibt mir irgendwelche unlesbaren Zeichen mit aus, obwohl ich nur die angegebenen Werte habe.
Ich nutze den GCC Kompiler.

Hinbekommen habe ich das aber trotzdem.
Und zwar füge ich einem String Zeichen für Zeichen von dem jeweiligen Eintrag von Vector<char>.
Danach mit cout << setw(11) << right << meinString;

Und es funktioniert alles sauber.
 
Zuletzt bearbeitet:
Hallo

Vielen Dank für die Hilfe.
Leider funktioniert das nicht....

Du hast da was übersehen:

b) Du machst dir std::string zunutze, indem du an die Zeichenkette ein 0 anhängst und den Vector dann in den Copy-Constructor einer std::string-Instanz einsetzt.

Bei dir also:
C++:
formatedValue.push_back(0);
string str(formatedValue.data());
cout<< setw(11)<< right;
cout<< str.c_str();

Gruss
cwriter
 
ups sorry,
hab das mit der 0 übersehen.
Welche Lösung ist performanter?

Braucht man die 0 deswegen, weil sonst die oben erwähnten unlesbaren Zeichen zu sehen sind?
Ich frage mich überhaupt, warum da diese unlesbaren Zeichen da sind.
Danke noch mal
 
ups sorry,
hab das mit der 0 übersehen.
Kein Problem, kommt vor.
Welche Lösung ist performanter?
Nun, normalerweise ist es schneller, von London nach Sydney direkt zu fliegen und nicht erst noch in Grönland zwischenzulanden, oder? ;) Der Weg ohne std::string ist schneller.
Braucht man die 0 deswegen, weil sonst die oben erwähnten unlesbaren Zeichen zu sehen sind?
Yep. Im Prinzip kommt das noch aus C-Zeiten. Wenn du einen String hast (per definitionem eine Zeichenkette), dann musst du ja wissen, wann der String zu Ende ist. Dazu gibt es im Prinzip 2 Möglichkeiten:
a) Man gibt im Vornherein an, wie lange der String ist (wird bei allgemeinen Byte-Arrays so gemacht). Problem hier: Die Angabe der Länge muss eine konstante Grösse (unsigned char/short/int/long etc.) sein. D.h.: Auch wenn die Zeichenkette nur 1 Byte lang ist, werden im Fall von int 4 Bytes vornedran gebraucht, um die Länge anzugeben. Umgekehrt ist bei einer 1-Bytigen Längenangabe das Problem, dass die Zeichenkette maximal 256 Zeichen lang sein kann (denn mehr geht nicht in ein byte/char).
b) Man definiert ein "Ende"-Zeichen. Einfachkeitshalber hat man 0 genommen. So kann die Zeichenkette theoretisch unendlich lang werden, es braucht immer nur 1 Byte, um die Länge anzugeben. Probleme: Um die Länge zu bestimmen, muss man durch den ganzen String iterieren und die 0 finden. Zudem gehen binäre Strings nicht (daher spricht man dort von Arrays).
Ich frage mich überhaupt, warum da diese unlesbaren Zeichen da sind.
Wie oben angesprochen, nehmen Funktionen, die Strings verarbeiten, alle Daten bis zu einem 0. Der Arbeitsspeicher ist voller Daten, die nicht druckbar sein müssen. Wenn also hinter deinem nicht-terminierten String noch Daten sind, werden die schlicht auch dargestellt, völlig wurst, ob die druckbar sind oder nicht.
Bitte.

Gruss
cwriter
 
Zurück