Установка точности / ширины поля в операторе << для всего вектора - PullRequest
0 голосов
/ 30 апреля 2020

Код, приведенный ниже, печатает вектор в std::cout.

struct vect {
    double x;
    double y;
};
std::ostream& operator<<(std::ostream& os, vect v){
    os << "[" << v.x << " " << v.y << "]";
    return os;
}

int main(){
    vect v = {1.0, 2.0};
    std::cout << v << std::endl;
    return 0;
}

Каким будет хороший способ контролировать ширину / точность каждого поля? Я мог бы жестко закодировать его в operator<<:

std::ostream& operator<<(std::ostream& os, vect v){
    os << "[" << std::setprecision(3) << std::setw(7) << v.x << " " << std::setprecision(3) << std::setw(7) << v.y << "]";
    return os;
}

, но я бы предпочел управлять им извне:

std::cout << std::setprecision(3) << std::setw(7) << v << std::endl;

Однако я думаю, что это только установит точность и ширину для первого поля вектора.

Я имею в виду сначала «getw» и «getprecision» в начале operator<<, а затем перенести их в другие поля. Есть ли способы извлечь эти вещи из потока, и основывается ли этот базовый проект на правильных предположениях? (Я не очень уверен в том, как работают iomanipulator; я просто знаю, чтобы отправить std::setw перед данными.)

Ответы [ 3 ]

1 голос
/ 30 апреля 2020

, как описано в комментариях, setprecision сохраняется, но setw - нет.

Предположим, вы хотите, чтобы setw применялся к каждому отдельному полю в вашем типе композиции, но не к символам форматирования вокруг него. Чтобы сделать это, посмотрите на свойство width, затем установите его для каждого из числовых полей c.

#include <iostream>
#include <iomanip>

struct coordinate {
    double x;
    double y;
};

std::ostream& operator<<(std::ostream& os, coordinate p) {
    auto w = os.width();
    os << std::setw(0) << "["  // we don't want the width yet
       << std::setw(w) << p.x  // set width on specific field
       << " " 
       << std::setw(w) << p.y  // set width on specific field
       << "]";
    return os;
}

int main() {
    coordinate value = { 1.000019, 2.000019 };
    std::cout << std::setprecision(3) << std::setw(7) << value << std::endl;
    std::cout << std::setprecision(6) << std::setw(7) << value << std::endl;
    std::cout << std::setprecision(1) << std::setw(3) << value << std::endl;
    return 0;
}

output:

[      1       2]  
[1.00002 2.00002]  
[  1   2]
0 голосов
/ 30 апреля 2020

Однако я думаю, что это только установит точность и ширину для первого поля вектора.

Я думаю, вы должны проверить это, прежде чем тратить больше времени, пытаясь "решить" его. .

(не совсем ответ, но я не могу процитировать, и т. Д. c в комментарии)

0 голосов
/ 30 апреля 2020

Это то, что я сделал. Это звуковой дизайн?

std::ostream& operator<<(std::ostream& os, vect v){
    auto p = os.precision();
    auto w = os.width();
    os << "[" << std::setprecision(p) << std::setw(w) << v.x << " " << std::setprecision(p) << std::setw(w) << v.y << "]";
    return os;
}
...