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
}
}
基本上我想打印这样的东西:
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
}
}