C将列与printf()对齐,每列后面正好有2个空格

C将列与printf()对齐,每列后面正好有2个空格,c,printf,scanf,C,Printf,Scanf,我相信我可能把这件事复杂化了,并在这里寻找了许多解决方案 这是C代码在命令行中编写一个双数字输入流,如“101666100066677788359”,默认为13个十进制位置(prec)和3个默认列(cols),因此输出实际上是 10.0000000000000 1.0000000000000 666.0000000000000 10000.0000000000000 666.0000000000000 77.0000000000000 88.0000000000000 3.00

我相信我可能把这件事复杂化了,并在这里寻找了许多解决方案

这是C代码在命令行中编写一个双数字输入流,如“101666100066677788359”,默认为13个十进制位置(prec)和3个默认列(cols),因此输出实际上是

    10.0000000000000 1.0000000000000 666.0000000000000
 10000.0000000000000 666.0000000000000 77.0000000000000
    88.0000000000000 3.0000000000000 5.0000000000000
     9.0000000000000
在3列中。(输入的所有数字必须小于等于10000)

我基本上需要输出数据如下所示(每列后面最多2个空格):

这是我的密码。您只需通过gcc编译.c文件,然后运行.exe并输入一个中间有空格的#以将其输出(格式化):

#包括//scanf()、fscanf()、fprintf()、fopen()
#包括//atoi(),getenv()
int main(int argc,char*argv[])
{
int cols=3;//列的默认值为3。
int prec=13;//精度的默认值为13位小数。
int count=0;//跟踪输入流的长度,即“10 55 13 666 77”的长度为5。
双x;
//获取命令行参数(如果存在)以设置精度。如果不存在,则不执行任何操作,只使用默认精度(13)
如果(argc>1)
{//从命令行获取操作数
prec=atoi(argv[1]);
cols=atoi(argv[2]);
}
//系统会提示用户输入
printf(“输入流编号:\n”);
//而循环将输出吐出并格式化
while(scanf(“%lf”,&x)!=EOF)
{
//星号(*)保持动态精度。精度的默认值为13。
printf(“%19.*f”,prec,x);
计数++;
//当count==cols时,\n输出为格式化列
如果(计数=cols)
{
printf(“\n”);
计数=0;
}
}
返回0;
}
我目前将列宽固定为19,但有人告诉我它需要是星号*,这样它就可以是动态的。只要我有不同大小的#作为输入,它们就不会始终在每列后面保留两个空格

我想我应该重新分配我的双x;这是我对char x[]数组的输入,但我想如果我问一下,可能会有一个更简单的实现。我有一种预感,它与每列的前导空格有关

因为我使用的是scanf(),有没有办法计算我的#的每个字符?比如,如果我的第一个数字是10.0000000000000,是否有一种方法来计算每个位置,这样我就可以合计(在本例中)一个int值=15,这样我就可以动态地填充每个数字


如果需要更具体的说明,请告诉我。

一种方法是在值到达数组时保存这些值,并跟踪每列中的最大值,然后格式化该值以确定其长度,并由此推断出要指定的值

下面是一些代码:

#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;
}
默认输出如下所示:

 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
$ ./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
$
或者有6个小数位和6列,看起来像这样:

 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
$ ./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
$
$。/fmt53 6
或具有5位小数和7列:

$ ./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
$
$。/fmt53 5 7
首先将所有内容放入一个数组中,以找到整数部分的最大长度,然后根据该长度和精度计算
字段的宽度

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

#define MAX_NUM 128

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.

    if (argc > 1) {
        prec = atoi(argv[1]);
        cols = atoi(argv[2]);
    }
    printf("Enter input stream numbers: \n");

    int count = 0;
    double val[MAX_NUM];
    double max = DBL_MIN;
    for(double x = 0; count < MAX_NUM && scanf("%lf", &x) != EOF;) {
        if(x > max)
            max = x;

        val[count++] = x;
    }

    int integer_width = snprintf(0, 0, "%d", (int)max);
    int field_width = integer_width + prec + 1;
    for(int i = 0; i < count; i++) {
        printf("%*.*f%s", field_width, prec, val[i], i % cols == 2 || i == count - 1 ? "\n" : "  ");
    }

    return 0;
}
#包括
#包括
#包括
#定义最大数量128
int main(int argc,char*argv[])
{
int cols=3;//列的默认值为3。
int prec=13;//精度的默认值为13位小数。
如果(argc>1){
prec=atoi(argv[1]);
cols=atoi(argv[2]);
}
printf(“输入流编号:\n”);
整数计数=0;
双值[最大值];
双最大值=DBL_最小值;
对于(双x=0;计数最大值)
max=x;
val[count++]=x;
}
int integer_WITH=snprintf(0,0,“%d”(int)max);
int field_width=integer_width+prec+1;
for(int i=0;i
缺点:

  • 仅支持
    MAX\u NUM
  • 处理输入的可怕方式
  • integer\u width
    是通过调用
    snprintf
    来计算的,而不是 真正最优

可以忽略//获取命令行参数(如果存在)来设置精度。如果没有,什么都不做,只使用默认精度(13),这对这个问题来说真的不重要。这完全取决于你想要什么,但是如果所有数字都是正数(在示例中),那么你需要在三列中的每一列中找到最大的数字,并对该数字进行试用格式。那会告诉你它有多宽。从这里开始,只需要生成一个合适的格式字符串,并忽略编译器对代码中非文字格式字符串的警告
#include <stdio.h>
#include <stdlib.h>
#include <float.h>

#define MAX_NUM 128

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.

    if (argc > 1) {
        prec = atoi(argv[1]);
        cols = atoi(argv[2]);
    }
    printf("Enter input stream numbers: \n");

    int count = 0;
    double val[MAX_NUM];
    double max = DBL_MIN;
    for(double x = 0; count < MAX_NUM && scanf("%lf", &x) != EOF;) {
        if(x > max)
            max = x;

        val[count++] = x;
    }

    int integer_width = snprintf(0, 0, "%d", (int)max);
    int field_width = integer_width + prec + 1;
    for(int i = 0; i < count; i++) {
        printf("%*.*f%s", field_width, prec, val[i], i % cols == 2 || i == count - 1 ? "\n" : "  ");
    }

    return 0;
}