Выравнивание вывода на терминал с помощью C ++ - PullRequest
3 голосов
/ 20 сентября 2011

У меня много проблем с настройкой вывода на терминал.Я хочу вывести вектор векторов viz vector< vector<double> > myvec; на выход, где myvec [i] занимает i-ю строку на терминале.Векторы, составляющие myvec, имеют размер 3

Вот так я пытаюсь его напечатать.

for(unsigned int i=0; i<myvec.size() ; ++i   )
{


cout<<myvec[i][0]<<"     "
    <<myvec[i][1]<<"     "
    <<myvec[i][2]<<'\n';
}

Когда я печатаю это для вывода, только столбец чисел myvec [i] [0] выравнивается правильно.Остальные цифры выглядят грязно.Есть ли хороший способ выровнять этот вывод?(Игнорируйте 0,7, напечатанные справа в строке 5 изображения)

enter image description here

Ответы [ 2 ]

6 голосов
/ 20 сентября 2011

Вы можете использовать setw(), чтобы установить минимальное количество символов, которое вы хотите записать, и left, чтобы вывести данные влево. Как это:

cout << setw(8) << left << myvec[i][0];

Это должно заполнить пустое пространство пробелами, но если нет, то вы можете сделать:

cout << setw(8) << left << setfill(' ') << myvec[i][0];

Для этого вам потребуется #include <iomanip>.

0 голосов
/ 20 сентября 2011

Всего пара замечаний о вашем коде:

Типы выравнивания

ответ quasiverse дает вам выравнивание влево, т.е. каждое число начинается с первой позиции символа.Удалите left, чтобы выровнять его по правому краю, т. Е. Каждое число начинается с последней позиции символа.

Выравнивание десятичных точек немного сложнее.Если вы хотите установить фиксированное количество цифр после десятичной запятой, то замените left на fixed и добавьте setprecision(), задав ему количество цифр, которое вы хотите после десятичной.Например, чтобы показать две цифры после десятичной дроби:

cout << setw(8) << fixed << setprecision(2) << myvec[i][0];

2-D Векторы

Вы объявляете vector< vector<double> > myvec;, но второстепенное (второе) измерение кажется жестко заданным в 3.Это означает, что вы создаете вектор векторов, где каждая строка представляет собой целый векторный объект с хранилищем для трех двойных чисел.

vector s не хранят свои данные внутри;фактический векторный объект просто хранит количество элементов, указатель на фактическое хранилище данных и, возможно, пару других вещей.Фактические данные хранятся в отдельном блоке.Это создаст много накладных расходов и фрагментацию памяти (каждая строка выделяет блок для хранения данных).

Например, для вектора 1000x3 в стеке имеется векторный объект верхнего уровня, массивиз 1000 векторных объектов (по одному на строку) в куче, и каждый из них указывает на блок из трех двойников, поэтому у вас есть 1001 объект в куче, и каждый доступ должен проходить через два указателя.Медленно и неэффективно.

vector излишне, если длина фиксирована.Поэтому я бы рекомендовал иметь вектор структур, каждая из которых имеет три двойных числа:

struct point {
    double x, y, z;
};
vector<point> myvec;

. Здесь все данные хранятся в одном блоке, поскольку point полностью автономен.Тогда ваш код:

for(unsigned int i = 0; i < myvec.size() ; ++i)
{
    cout << setw(8) << left << myvec[i].x << ' ' << setw(8) << left << myvec[i].y 
        << ' ' << setw(8) << left << myvec[i].z << endl;
}

Или, итератор C ++, способ сделать это:

for(vector<point>::const_iterator elem = myvec.begin(); elem != myvec.end() ; ++elem)
{
    cout << setw(8) << left << elem.x << ' ' << setw(8) << left << elem.y 
        << ' ' << setw(8) << left << elem.z << endl;
}

Это сохраняет кучу вызовов в operator[].Если ваш компилятор поддерживает новый стандарт C ++ 11, вы можете изменить строку for() на:

for(auto elem = myvec.begin(); elem != myvec.end() ; ++elem)

, где auto говорит компилятору сделать elem того же типа, что и myvec.begin() возвращается.Другим способом C ++ 11, который с меньшей вероятностью будет поддерживаться, является цикл для цикла :

for(auto elem: myvec)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...