C align columns w/ printf() w/ exactly 2 spaces after each column

ennth

I believe I might be over-complicating this and searched many solutions on here.

This is C code to write an input stream in command line of double numbers like "10 1 666 10000 666 77 88 3 5 9" with default 13 decimal positions (prec) and default 3 columns (cols), so that output would actually be

    10.0000000000000 1.0000000000000 666.0000000000000
 10000.0000000000000 666.0000000000000 77.0000000000000
    88.0000000000000 3.0000000000000 5.0000000000000
     9.0000000000000

in 3 columns. (All numbers input must be 10,000 or less).

I basically need my output data to look like this (2 spaces max after each column):

enter image description here

5163.1575670644243  6806.8180791650138  8977.2739646595655
2598.0792870876185  7162.5237586596268  6691.2041993469038
1043.6422009949033  6922.8216193121125     3.0480056154058
9926.6081118198181   100.3082369457076  5135.1567125461588
7808.2382885219886  1439.6542863246559   249.6179692983795
 214.0065309610279  9280.5883968626968  2687.3871883297220
7612.8426770836513  6644.2027649769589  8364.5604419080173
4740.7550279244360   254.6181218909269  2500.3814813684498
2293.6803491317482   835.3306680501725  5962.7923215430155
9622.5988341929387    57.3069246498001  1557.9630726035341
8398.5614795373385  5958.4870143742182  2568.3835566270945
9935.9135715811644  3410.1040681173131   982.0299691763055
8393.5613269447913  9066.2766808069100  4896.4546037171549
7597.8422193060087  8551.5661488692895  1076.6432081057162
1911.3635059663686  7586.8418836024048  9282.8936429944770
4696.1433149204995  1388.0423596911528  1936.3642689291055
3408.4091921750542  3556.4137089144565  9241.8923917355878
5003.4578691976685  3366.7130954924160  4270.1303140354621
 620.6292916653950  4700.7538071840572  1766.0538956877347
 441.6238288521989  8153.8591875972779

Here is my code. You can simply compile the .c file via gcc and run the .exe and input a #'s with whitespace in between to have it output (formatted):

#include <stdio.h>   // scanf(), fscanf(), fprintf(), fopen()
#include <stdlib.h>  // atoi(), getenv()

int main(int argc, char *argv[])
{
   int cols = 3; // default value for columns is 3.
   int prec = 13; // default value for precision is 13 decimal places.

   int count =  0; // keep track of length of input stream, i.e. "10 55 13 666 77" has length 5.
   double x;

   // Get a command line argument (if it exists) to set precision. If it's not there, do nothing and just use default precision (13)
   if (argc > 1)
   {  // get an operand from the command line
      prec = atoi(argv[1]);
      cols = atoi(argv[2]);
   }

   // User gets prompted to enter input
   printf("Enter input stream numbers: \n");

   // While loop spits output and formats it
   while (scanf("%lf", &x) != EOF)
   {
   // Asterisk(*) keeps precision for dynamic. Default value for precision is 13.


      printf("%19.*f", prec, x);
      count++;

   // When count == cols, \n is output to format columns
   if (count == cols) 
   {
      printf("\n");
      count = 0;
   }

   }
      return 0;
}

I currently have the column width fixed at 19, but something tells me it needs to be an asterisk *, so it can be dynamic. As soon as I have different sized #'s as input, they do not stay 2 spaces after each column consistently.

I thought I should re-assign my double x; which is my input to maybe a char x[] array, but I thought if I asked there might be an easier implementation. I'm having a hunch it has something to do with the leading spaces of each column #.

Since I'm using scanf(), is there a way to count each character of my #'s? like if my first number is 10.0000000000000, is there a way to count each position, so I can total up (in this case) an int value = 15, that way I can pad each number dynamically?

Please let me know if I need to be more specific.

Jonathan Leffler

One way to do it is to save the values as they arrive in an array, and keep track of the largest value in each column, then format that value to find out how long it is, and from that deduce the values to specify.

Here's some code that does that:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    int cols = 3;
    int prec = 13;

    if (argc > 3)
    {
        fprintf(stderr, "Usage: %s [precision [columns]]\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    if (argc > 1)
        prec = atoi(argv[1]);
    if (argc > 2)
        cols = atoi(argv[2]);
    double max[cols];
    for (int i = 0; i < cols; i++)
        max[i] = 0.0;

    enum { MAX_DATA = 100 };
    double data[MAX_DATA];
    int count =  0;
    double x;
    while (scanf("%lf", &x) == 1 && count < MAX_DATA)
    {
        int colnum = count % cols;
        if (x > max[colnum])
            max[colnum] = x;
        data[count++] = x;
    }

    int width[cols];
    const char *pad[cols];
    for (int i = 0; i < cols; i++)
    {
        pad[i] = (i == 0) ? "" : "  ";
        width[i] = snprintf(0, 0, "%.*f", prec, max[i]);
        if (width[i] < 4 + prec)
            width[i] = 4 + prec;
    }

    for (int i = 0; i < count; i++)
    {
        int colnum = i % cols;
        printf("%s%*.*f", pad[colnum], width[colnum], prec, data[i]);
        if (colnum == cols - 1)
            putchar('\n');
    }
    if (count % cols != 0)
        putchar('\n');

    return 0;
}

Note that the code is careful to reject too many arguments, and not to access arguments that don't exist. I also removed the prompt; there's no way I'm typing the numbers by hand, and when the input comes from a file, the prompt is just a nuisance.

Also, the use of snprintf() with zero length (and optionally a null pointer) is documented by the standard as a way to get the amount of space needed to format the string.

Given some sample data like this (randomly generated, but then rigged so that there's a 10k value in each column, and also a 'single digit before the decimal point' value in each column — in the default 3-column layout):

2730.8075416749843 9153.7050562644145 8264.2778874481955
5393.9722906483921 9659.6077493184748 59.6077493184748
4973.9718947965630 3.7623787002290 5975.6392547304667 682.2153319663826
6236.5964619743863 7786.2954141327737 3.7623787002290 6735.6044984396849
1069.6226524395413 8709.7209141371932 3854.7386329491574 3.7623787002290
4960.9318291197014 40.3314639772034 9017.1314461534275
1717.9459363110184 8682.9285936347133 10000 6671.2353105858210
4119.1373095038844 70.3291668437700 4528.3226201367906
1926.8741591097082 2101.4643722293158 760.9213269470772 10000
7366.6932284462664 1287.1299466478447 3418.7415326626078
3144.9791945834349 2385.3575762876035 3779.9164071168789
9743.9571880258318 10000 7432.8398636749780 3011.9532204395937
5883.0779787486517

The default output looks like this:

 2730.8075416749843   9153.7050562644145   8264.2778874481955
 5393.9722906483921   9659.6077493184748     59.6077493184748
 4973.9718947965630      3.7623787002290   5975.6392547304667
  682.2153319663826   6236.5964619743863   7786.2954141327737
    3.7623787002290   6735.6044984396849   1069.6226524395413
 8709.7209141371932   3854.7386329491574      3.7623787002290
 4960.9318291197014     40.3314639772034   9017.1314461534275
 1717.9459363110184   8682.9285936347133  10000.0000000000000
 6671.2353105858210   4119.1373095038844     70.3291668437700
 4528.3226201367906   1926.8741591097082   2101.4643722293158
  760.9213269470772  10000.0000000000000   7366.6932284462664
 1287.1299466478447   3418.7415326626078   3144.9791945834349
 2385.3575762876035   3779.9164071168789   9743.9571880258318
10000.0000000000000   7432.8398636749780   3011.9532204395937
 5883.0779787486517

Or with 6 decimal places and 6 columns, it looks like this:

$ ./fmt53 6 6 < data
2730.807542   9153.705056  8264.277887   5393.972291  9659.607749     59.607749
4973.971895      3.762379  5975.639255    682.215332  6236.596462   7786.295414
   3.762379   6735.604498  1069.622652   8709.720914  3854.738633      3.762379
4960.931829     40.331464  9017.131446   1717.945936  8682.928594  10000.000000
6671.235311   4119.137310    70.329167   4528.322620  1926.874159   2101.464372
 760.921327  10000.000000  7366.693228   1287.129947  3418.741533   3144.979195
2385.357576   3779.916407  9743.957188  10000.000000  7432.839864   3011.953220
5883.077979
$

Or with 5 decimal places and 7 columns:

$ ./fmt53 5 7 < data
2730.80754  9153.70506   8264.27789   5393.97229   9659.60775    59.60775  4973.97189
   3.76238  5975.63925    682.21533   6236.59646   7786.29541     3.76238  6735.60450
1069.62265  8709.72091   3854.73863      3.76238   4960.93183    40.33146  9017.13145
1717.94594  8682.92859  10000.00000   6671.23531   4119.13731    70.32917  4528.32262
1926.87416  2101.46437    760.92133  10000.00000   7366.69323  1287.12995  3418.74153
3144.97919  2385.35758   3779.91641   9743.95719  10000.00000  7432.83986  3011.95322
5883.07798
$

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

Memory Error when running my C++ code w/ Rcpp/RcppArmadillo : Can't identify exactly what is wrong after debugging with valgrind

分類Dev

sql unique column w

分類Dev

Printf w / EclipseCDTの問題

分類Dev

How to join two columns using 'on' statement if values in each column are not exactly the same?

分類Dev

Angular Material Select w / Columns

分類Dev

Treat spaces as spaces after n column

分類Dev

Add 2 columns and create new column after those 2 (R)

分類Dev

$(selector).each on table rows w / Laravel

分類Dev

Replace integers in dataframe column w/ 'Y'

分類Dev

char c [] = {'J'、 'K'、 'W'}; printf( "%s"、c)が "JKWJKW"を出力するのはなぜですか?

分類Dev

in R, how can I calculate y/y and w/w in a data frame, based on different columns criteria?

分類Dev

Sencha touch 2 in a W8 application

分類Dev

async / await w / koa 2&mongoose

分類Dev

C#の `PROCESSENTRY32W`?

分類Dev

Programmatically do "Git blame -w" in C#

分類Dev

ETag形式w3c

分類Dev

c++ binary tree help w/template

分類Dev

Error w/declaration on else statement (C++)

分類Dev

Pandas Fillna of Multiple Columns with Mode of Each Column

分類Dev

Possible to upsert in Postgres on conflict on exactly one of 2 columns?

分類Dev

Delete any number of Columns in 2D dynamic array and resize the matrix size after column deletion

分類Dev

max732x.c I2C IO Expander + GPIO Keys w/ Linux Device Tree not working

分類Dev

Exactly align picture to heading text

分類Dev

whileループw / 2条件は機能しませんc ++

分類Dev

W3C Duplicate ID ...しかし、2つのIDが必要です

分類Dev

How to turn off w3c in chromedriver to address the error unknown command: Cannot call non W3C standard command while in W3C

分類Dev

mingw-w64 gcc 7.1で警告なしにsize_tをprintfする方法は?

分類Dev

ifelse inside for loop w / 2条件

分類Dev

.WファイルのCソース

Related 関連記事

  1. 1

    Memory Error when running my C++ code w/ Rcpp/RcppArmadillo : Can't identify exactly what is wrong after debugging with valgrind

  2. 2

    sql unique column w

  3. 3

    Printf w / EclipseCDTの問題

  4. 4

    How to join two columns using 'on' statement if values in each column are not exactly the same?

  5. 5

    Angular Material Select w / Columns

  6. 6

    Treat spaces as spaces after n column

  7. 7

    Add 2 columns and create new column after those 2 (R)

  8. 8

    $(selector).each on table rows w / Laravel

  9. 9

    Replace integers in dataframe column w/ 'Y'

  10. 10

    char c [] = {'J'、 'K'、 'W'}; printf( "%s"、c)が "JKWJKW"を出力するのはなぜですか?

  11. 11

    in R, how can I calculate y/y and w/w in a data frame, based on different columns criteria?

  12. 12

    Sencha touch 2 in a W8 application

  13. 13

    async / await w / koa 2&mongoose

  14. 14

    C#の `PROCESSENTRY32W`?

  15. 15

    Programmatically do "Git blame -w" in C#

  16. 16

    ETag形式w3c

  17. 17

    c++ binary tree help w/template

  18. 18

    Error w/declaration on else statement (C++)

  19. 19

    Pandas Fillna of Multiple Columns with Mode of Each Column

  20. 20

    Possible to upsert in Postgres on conflict on exactly one of 2 columns?

  21. 21

    Delete any number of Columns in 2D dynamic array and resize the matrix size after column deletion

  22. 22

    max732x.c I2C IO Expander + GPIO Keys w/ Linux Device Tree not working

  23. 23

    Exactly align picture to heading text

  24. 24

    whileループw / 2条件は機能しませんc ++

  25. 25

    W3C Duplicate ID ...しかし、2つのIDが必要です

  26. 26

    How to turn off w3c in chromedriver to address the error unknown command: Cannot call non W3C standard command while in W3C

  27. 27

    mingw-w64 gcc 7.1で警告なしにsize_tをprintfする方法は?

  28. 28

    ifelse inside for loop w / 2条件

  29. 29

    .WファイルのCソース

ホットタグ

アーカイブ