Development Tip

cout << 인쇄시 C ++ 정렬

yourdevel 2020. 12. 6. 22:11
반응형

cout << 인쇄시 C ++ 정렬


를 사용하여 인쇄 할 때 텍스트를 정렬하는 방법이 std::cout있습니까? 탭을 사용하고 있지만 단어가 너무 크면 더 이상 정렬되지 않습니다.

Sales Report for September 15, 2010
Artist  Title   Price   Genre   Disc    Sale    Tax Cash
Merle   Blue    12.99   Country 4%  12.47   1.01    13.48
Richard Music   8.49    Classical   8%  7.81    0.66    8.47
Paula   Shut    8.49    Classical   8%  7.81    0.72    8.49

그것을 할 수있는 ISO C ++ 표준 방법이다 #include <iomanip>사용 등의 조종 IO std::setw. 그러나 이러한 io 조작기는 텍스트에도 사용하기가 정말 고통스럽고 숫자 서식 지정에 사용할 수 없습니다 (달러 금액을 소수점에 정렬하고 올바른 유효 자릿수 등을 갖고 싶다고 가정합니다). .). 일반 텍스트 레이블의 경우에도 첫 번째 줄의 첫 번째 부분에 대한 코드는 다음과 같습니다.

// using standard iomanip facilities
cout << setw(20) << "Artist"
     << setw(20) << "Title"
     << setw(8) << "Price";
// ... not going to try to write the numeric formatting...

Boost 라이브러리 를 사용할 수 있다면 대신 Boost.Format 라이브러리를 실행하고 (걷지 말고) 사용하십시오 . 표준 iostream과 완벽하게 호환되며 printf / Posix 형식화 문자열을 사용하여 쉽게 형식화 할 수있는 모든 장점을 제공하지만 iostreams 자체의 성능과 편리함을 잃지 않습니다. 예를 들어, 처음 두 줄의 첫 부분은 다음과 같습니다.

// using Boost.Format
cout << format("%-20s %-20s %-8s\n")  % "Artist" % "Title" % "Price";
cout << format("%-20s %-20s %8.2f\n") % "Merle" % "Blue" % 12.99;

참고 항목 : C ++ 코드에서 어떤 CI / O 라이브러리를 사용해야합니까?

struct Item
{
   std::string     artist;
   std::string     c;
   integer         price;  // in cents (as floating point is not acurate)
   std::string     Genre;
   integer         disc;
   integer         sale;
   integer         tax;
};

std::cout << "Sales Report for September 15, 2010\n"
          << "Artist  Title   Price   Genre   Disc    Sale    Tax Cash\n";
FOREACH(Item loop,data)
{
    fprintf(stdout,"%8s%8s%8.2f%7s%1s%8.2f%8.2f\n",
          , loop.artist
          , loop.title
          , loop.price / 100.0
          , loop.Genre
          , loop.disc , "%"
          , loop.sale / 100.0
          , loop.tax / 100.0);

   // or

    std::cout << std::setw(8) << loop.artist
              << std::setw(8) << loop.title
              << std::setw(8) << fixed << setprecision(2) << loop.price / 100.0
              << std::setw(8) << loop.Genre
              << std::setw(7) << loop.disc << std::setw(1) << "%"
              << std::setw(8) << fixed << setprecision(2) << loop.sale / 100.0
              << std::setw(8) << fixed << setprecision(2) << loop.tax / 100.0
              << "\n";

    // or

    std::cout << boost::format("%8s%8s%8.2f%7s%1s%8.2f%8.2f\n")
              % loop.artist
              % loop.title
              % loop.price / 100.0
              % loop.Genre
              % loop.disc % "%"
              % loop.sale / 100.0
              % loop.tax / 100.0;
}

IO 조작기가 필요한 것입니다. 특히 setw 입니다. 다음은 참조 페이지의 예입니다.

// setw example
#include <iostream>
#include <iomanip>
using namespace std;

int main () {
  cout << setw (10);
  cout << 77 << endl;
  return 0;
}

필드를 왼쪽과 오른쪽으로 정렬하는 작업은 leftright조작기로 수행됩니다 .

Also take a look at setfill. Here's a more complete tutorial on formatting C++ output with io manipulators.


The setw manipulator function will be of help here.


Another way to make column aligned is as follows:

using namespace std;

cout.width(20); cout << left << "Artist";
cout.width(20); cout << left << "Title";
cout.width(10); cout << left << "Price";
...
cout.width(20); cout << left << artist;
cout.width(20); cout << left << title;
cout.width(10); cout << left << price;

We should estimate maximum length of values for each column. In this case, values of "Artist" column should not exceed 20 characters and so on.


At the time you emit the very first line,

Artist  Title   Price   Genre   Disc    Sale    Tax Cash

to achieve "alignment", you have to know "in advance" how wide each column will need to be (otherwise, alignment is impossible). Once you do know the needed width for each column (there are several possible ways to achieve that depending on where your data's coming from), then the setw function mentioned in the other answer will help, or (more brutally;-) you could emit carefully computed number of extra spaces (clunky, to be sure), etc. I don't recommend tabs anyway as you have no real control on how the final output device will render those, in general.

Back to the core issue, if you have each column's value in a vector<T> of some sort, for example, you can do a first formatting pass to determine the maximum width of the column, for example (be sure to take into account the width of the header for the column, too, of course).

If your rows are coming "one by one", and alignment is crucial, you'll have to cache or buffer the rows as they come in (in memory if they fit, otherwise on a disk file that you'll later "rewind" and re-read from the start), taking care to keep updated the vector of "maximum widths of each column" as the rows do come. You can't output anything (not even the headers!), if keeping alignment is crucial, until you've seen the very last row (unless you somehow magically have previous knowledge of the columns' widths, of course;-).

참고URL : https://stackoverflow.com/questions/2485963/c-alignment-when-printing-cout

반응형