2009-09-19 2 views
7

Я пытался отформатировать вывод на консоль в течение самого долгого времени, и ничего не происходит. Я пытаюсь использовать как можно больше iomanip и функции ofstream&.Форматирование вывода консоли C++

void list::displayByName(ostream& out) const 
{ 
node *current_node = headByName; 

// I have these outside the loop so I dont write it everytime. 

out << "Name\t\t" << "\tLocation" << "\tRating " << "Acre" << endl; 
out << "----\t\t" << "\t--------" << "\t------ " << "----" << endl; 

while (current_node) 
{ 
    out << current_node->item.getName()// equivalent tabs dont work? 
     << current_node->item.getLocation() 
    << current_node->item.getAcres() 
    << current_node->item.getRating() 
    << endl; 

    current_node = current_node->nextByName; 
} 

// The equivalent tabs do not work because I am writing names, 
// each of different length to the console. That explains why they 
// are not all evenly spaced apart. 
} 

Это их все, что я могу использовать, чтобы все было правильно выровнено между собой? Функции, которые я вызываю, понятны и имеют разные длины, поэтому они не очень хорошо выравниваются друг с другом.

Я пробовал практически все в iomanip.

ответ

2

Вы можете написать процедуру, которая всегда печатает одинаковое количество символов в стандартном выходе. что-то вроде

string StringPadding(string original, size_t charCount) 
{ 
    original.resize(charCount, ' '); 
    return original; 
} 

, а затем использовать, как это в вашей программе

void list::displayByName(ostream& out) const 
{ 
    node *current_node = headByName; 

    out << StringPadding("Name", 30) 
     << StringPadding("Location", 10) 
     << StringPadding("Rating", 10) 
     << StringPadding("Acre", 10) << endl; 
    out << StringPadding("----", 30) 
     << StringPadding("--------", 10) 
     << StringPadding("------", 10) 
     << StringPadding("----", 10) << endl; 

    while (current_node) 
    { 
     out << StringPadding(current_node->item.getName(), 30) 
      << StringPadding(current_node->item.getLocation(), 10) 
      << StringPadding(current_node->item.getRating(), 10) 
      << StringPadding(current_node->item.getAcres(), 10) 
      << endl; 
     current_node = current_node->nextByName; 
    } 
} 
3

Откажитесь на вкладках. Вы должны иметь возможность использовать io-манипуляторы для установки ширины поля, символа заполнения и флага формата (чтобы получить право налево или вправо). Используйте те же значения для заголовков, что и для данных, и все должно получиться красиво.

Также обратите внимание на то, что вы переключили рейтинг и Acres в свой пример.

15

Думайте об этом, используя Microsoft Excel :) Вы думаете о своем потоке как о поле. Поэтому вы сначала устанавливаете ширину поля, затем вставляете текст в это поле. Например:

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

int main() 
{ 
    using namespace std; 

    string firstName = "firstName", 
      secondName = "SecondName", 
      n = "Just stupid Text"; 
    size_t fieldWidth = n.size(); // length of longest text 

    cout << setw(fieldWidth) << left << firstName << endl // left padding 
     << setw(fieldWidth) << left << secondName << endl 
     << setw(fieldWidth) << left << n << endl; 

    cout << setw(fieldWidth) << right << firstName << endl // right padding 
     << setw(fieldWidth) << right << secondName << endl 
     << setw(fieldWidth) << right << n << endl; 
} 

......

alt text

......

Ширина поля не означает ничего, кроме ширины text + spaces. Вы могли бы fill ничего, кроме пространства:

string name = "My first name"; 
cout << setfill('_') << setw(name.size() + 10) << left << name; 

.....

output:: 
My first name__________ 

......

Я думаю, что лучший способ выяснить свой формат, то, напишите новый форматтер, который сделает все, что вы хотите:

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

std::ostream& field(std::ostream& o) 
{ 
    // usually the console is 80-character wide. 
    // divide the line into four fields. 
    return o << std::setw(20) << std::right; 
} 

int main() 
{ 
    using namespace std; 

    string firstName = "firstName", 
      secondName = "SecondName", 
      n = "Just stupid Text"; 
    size_t fieldWidth = n.size(); 

    cout << field << firstName << endl 
     << field << secondName << endl 
     << field << n << endl; 
} 

Если вы начали думать о параметризованных манипуляторах rs, только тот, который принимает один параметр int или long, прост в реализации, другие типы действительно неясны, если вы не знакомы с потоками в C++.

+3

+1 для стандартных Io манипуляторов (setw и др), +1 для определения пользовательского iomanip, -1 для Excel – outis

+0

И вы можете также ограничить размер строки, которая будет печататься только в случае, если у вас есть большой строки (такие как полные имена) – Vargas

6

Boost имеет библиотеку форматов, которая позволяет вам легко форматировать нашу учетную запись, как старый C printf(), но с безопасностью типа C++.

Помните, что старый C printf() позволяет указать ширину поля. Это пространство заполняет поле, если выход ограничен (обратите внимание, что он не справляется с полями большого размера).

#include <iostream> 
#include <iomanip> 
#include <boost/format.hpp> 

struct X 
{ // this structure reverse engineered from 
    // example provided by 'Mikael Jansson' in order to make this a running example 

    char*  name; 
    double  mean; 
    int   sample_count; 
}; 
int main() 
{ 
    X stats[] = {{"Plop",5.6,2}}; 

    // nonsense output, just to exemplify 

    // stdio version 
    fprintf(stderr, "at %p/%s: mean value %.3f of %4d samples\n", 
      stats, stats->name, stats->mean, stats->sample_count); 

    // iostream 
    std::cerr << "at " << (void*)stats << "/" << stats->name 
       << ": mean value " << std::fixed << std::setprecision(3) << stats->mean 
       << " of " << std::setw(4) << std::setfill(' ') << stats->sample_count 
       << " samples\n"; 

    // iostream with boost::format 
    std::cerr << boost::format("at %p/%s: mean value %.3f of %4d samples\n") 
       % stats % stats->name % stats->mean % stats->sample_count; 
} 
Смежные вопросы