C中的输出缩进

Output indentation in C

基本上我想打印这样的东西:

Process No.(Size)    Block No.(Size)
1(200)               3(300)
2(3)                 1(50)
3(1000)              4(1200)

由于间距是可变的,如何通过%d中的宽度说明符来实现?

printf("%d(%d)%d(%d)",processNo,processSize,blockNo,blockSize)

间距值放在哪里?

您可以先将 table 的每个 'field' 打印成一个字符串,然后使用 left-justified、fixed-width 格式说明符打印每个这样的字段字符串。后者是使用 - 标志和 %s 格式说明符(即 -n%s)中的 width 值来完成的。

以下代码显示了您所需要的内容(我使用字段来保存列标题和每行数据,但这是一个 'optional extra')。

#include <stdio.h>

int main(void)
{
    // Test data ...
    int procNo[3] = { 1, 2, 3 };
    int procSize[3] = { 200, 3, 1000};
    int blockNo[3] = { 3, 1, 4 };
    int blockSize[3] = { 300, 50, 1200 };

    char procField[32] = "Process No.(Size)";
    char blockField[32] = "Block No.(Size)";

    // Print rubric ...
    printf("%-22s%-22s\n", procField, blockField);

    // Print data rows ...
    for (int i = 0; i < 3; ++i) {
        // Write each field to string ...
        snprintf(procField, sizeof(procField), "%d(%d)", procNo[i], procSize[i]);
        snprintf(blockField, sizeof(blockField), "%d(%d)", blockNo[i], blockSize[i]);
        // ... then print fields as left-justified, fixed-length fields
        printf("%-22s%-22s\n", procField, blockField);
    }
    return 0;
}

有关如何将宽度作为参数传递给 printf 的示例,请参阅 printf format string 中的 'Width field' 小节。

我从Finding the length of an integer in C得到宽度算法。

我在 Code Chef. If you intend to compile this code with gcc, you will need the -lm option to bring in the library for math.h. See How to compile a C program that uses math.h? 测试了我的代码。

如果您需要不同的 table header,您可以调整 printspaces(11-w) 中的常量 11 和 printspaces(5-w) 中的 5 直到数据与 header.

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

int width(int v){
    return floor(log10(abs(v))) + 1;
}

int printspaces(int s){
    int x;
    for (x=0;x<s;x++)
        printf(" ");
}

int main(void){
    int i,j,w;
    int a[3][4] = {{1,200,3,300},{2,3,1,50},{3,1000,4,1200}};
    //int a[3][4] = {{10,200,37,3000},{278,3565,1131,50},{390,100,4567,1200}};
    char *separator[4]  = {"","","","\n"};
    printf("Process No.(Size)   Block No.(Size)\n");
    for(i=0;i<3;i++){
        for (j=0;j<4;j++){
            w = width(a[i][j]);
            if (j%2==0){
                printspaces(11-w);
                printf("%*d%s",w,a[i][j],separator[j]);
            }
            else{
                printf("(%*d)",w,a[i][j]);
                printspaces(5-w);
                printf("%s",separator[j]);
            }
        }
    }
    return 0;
}

结果如下(针对代码中的两个示例数组):

int a[3][4] = {{1,200,3,300},{2,3,1,50},{3,1000,4,1200}};

Process No.(Size)   Block No.(Size)
          1(200)            3(300)  
          2(3)              1(50)   
          3(1000)           4(1200) 


int a[3][4] = {{10,200,37,3000},{278,3565,1131,50},{390,100,4567,1200}};

Process No.(Size)   Block No.(Size)
         10(200)           37(3000) 
        278(3565)        1131(50)   
        390(100)         4567(1200) 

printf 有两个 seldom-used 功能可以简单直接地完成此操作。

第一个特征是 printf 的 return 值。是的,printf 实际上是 return 的东西,它是打印的字符数。考虑以下两行代码:

int width = printf("Process No.(Size)    ");
int used  = printf("%d(%d)", procNum[i], procSize[i]);

第一行打印列 header,并将变量 width 设置为 header 中的字符数。第二行打印进程信息,并将变量 used 设置为打印两个数字和括号所需的字符数。因此,进程信息结束和块信息开始之间所需的 space 个字符数就是 width - used.

第二个功能是可变字段宽度说明符。来自手册页:“字段宽度或精度,或两者,可以用星号表示 '*' [...] 在这种情况下,int 参数提供字段宽度或精度。 考虑以下代码行:

printf("%*s", width - used, "");

代码使用 "%s" 转换说明符打印字符串,但字符串 "" 为空,因此通常不会打印任何内容。但是我们使用星号作为字段宽度。因此参数 before 字符串 (width - used) 提供字段宽度。该字符串将用 spaces 填充以填充该宽度。

注意,如果width - used小于1,代码应该将字段宽度设置为1,这样在进程信息和块信息之间至少插入一个space。

将它们放在一起,代码如下所示:

#include <stdio.h>
#define max(a,b) ((a) > (b) ? (a) : (b))

int main(void)
{
    int procNum[]   = { 1, 2, 3 };
    int procSize[]  = { 200, 3, 1000 };
    int blockNum[]  = { 3, 1, 4 };
    int blockSize[] = { 300, 50, 1200};

    int width = printf("Process No.(Size)    ");    // print first column header, and save the width
    printf("Block No.(Size)\n");

    for (int i = 0; i < 3; i++)
    {
        int used = printf("%d(%d)", procNum[i], procSize[i]);      // print process information, and save the number of characters used
        printf("%*s%d(%d)\n", max(width - used, 1), "", blockNum[i], blockSize[i]);   // print spaces followed by the block information
    }
}