2009-09-19 40 views
7

He estado tratando de formatear la salida a la consola por más tiempo y nada está sucediendo realmente. He intentado utilizar tanto de iomanip como puedo y las funciones de salida ofstream&.Dar formato a la salida de la consola 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. 
} 

¿Hay algo que pueda usar para alinearlo correctamente? Las funciones que llamo se explican por sí mismas y tienen diferentes longitudes, por lo que no se alinean muy bien entre ellas.

He intentado casi todo en iomanip.

Respuesta

2

Puede escribir un procedimiento que siempre imprima el mismo número de caracteres en la salida estándar. algo así como

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

y luego usar como esto en su programa de

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

renunciar a las pestañas. Debería poder usar io manipuladores para establecer el ancho del campo, el carácter de relleno y el indicador de formato (para obtener la justificación a la izquierda o a la derecha). Use los mismos valores para los títulos que para los datos, y todo debería salir bien.

También tenga en cuenta que ha cambiado la clasificación y Acres en su ejemplo.

15

Piénselo como usando Microsoft Excel :) Piensa en la secuencia como campos. Entonces, primero establece el ancho del campo y luego inserta el texto en ese campo. Por ejemplo:

#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

......

la anchura del campo significa nada más que la anchura de la text + spaces. Usted podría fill que no sea nada espacios:

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

.....

output:: 
My first name__________ 

......

Creo que la mejor forma de hacerlo es averiguar el formato de entonces, escriba un nuevo formateador que hace todo lo que quiere:

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

Si usted comenzó a pensar en manipulato parametrizado rs, solo que aceptan un int o long parámetro son fáciles de implementar, otros tipos son realmente oscuros si no está familiarizado con las transmisiones en C++.

+3

+1 para manipuladores estándar IO (setw y al), +1 para definir una iomanip encargo, -1 para Excel – outis

+0

Y también se puede limitar el tamaño de la cadena que se va a imprimir en caso de que tienen grandes cadenas (como nombres completos) – Vargas

6

Boost tiene una biblioteca de formato que le permite formatear fácilmente la salida como la antigua C printf() pero con la seguridad tipo C++.

Recuerde que el antiguo C printf() le permitió especificar un ancho de campo. Este espacio llena el campo si la salida es de tamaño insuficiente (obsérvese que no se ocupa de campos sobredimensionados).

#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; 
} 
Cuestiones relacionadas