如何修复C语言中二维数组表格数据与列标题的错位问题?
修复C语言二维数组表格打印对齐问题
要以表格形式展示5行20列的grades二维数组(行代表学生分数,列代表不同测试),但原代码打印出的表格从第11列开始出现错位——原因是列标题[10]为两位数,比前面的一位数标题多占一个字符,导致数据列与标题列无法对齐。同时需要解决多位数数据的表格对齐问题。
原代码
#include<stdio.h> int main(){ int grades[5][20] = { {1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6 }, {1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6 }, {1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6 }, {1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6 }, {1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6 } }; printf( " " ); // Offsets the column header from sidesways for (int i=0; i<20; i++) { printf( " [%d]", i ); // prints 20 column headers at top } for (int i=0; i<5; i++){ printf( "\nrow[%d] ", i ); // prints rows for (int j=0; j<20; j++){ printf( "%-4d", grades[i][j] ); } // inner for loop ends here } // outer for loop ends here } // main ends here
原输出
[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] row[0] 1 2 3 4 5 6 0 1 2 3 4 5 6 0 1 2 3 4 5 6 row[1] 1 2 3 4 5 6 0 1 2 3 4 5 6 0 1 2 3 4 5 6 row[2] 1 2 3 4 5 6 0 1 2 3 4 5 6 0 1 2 3 4 5 6 row[3] 1 2 3 4 5 6 0 1 2 3 4 5 6 0 1 2 3 4 5 6 row[4] 1 2 3 4 5 6 0 1 2 3 4 5 6 0 1 2 3 4 5 6
解决方案
1. 修复列标题与数据的对齐问题
错位根源是列标题的宽度不统一——一位数索引的标题(如[0])占3个字符,两位数索引(如[10])占4个字符。只需给列标题的数字部分设置固定宽度,让所有标题项的宽度一致:
修改列标题的打印代码,将printf( " [%d]", i );改为:
printf( " [%2d]", i );
%2d会让数字占2个字符宽度,不足的前面补空格,这样[0]会变成[ 0],每个标题项都占5个字符宽度。
同时,数据的打印格式也要对应调整为相同宽度,将printf( "%-4d", grades[i][j] );改为:
printf( "%-5d", grades[i][j] );
这样每个数据项也占5个字符宽度,和标题项完全对齐。
调整后的完整代码:
#include<stdio.h> int main(){ int grades[5][20] = { {1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6 }, {1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6 }, {1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6 }, {1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6 }, {1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6 } }; printf( " " ); // 调整偏移量适配新的标题宽度 for (int i=0; i<20; i++) { printf( " [%2d]", i ); // 固定数字宽度为2,所有标题项宽度一致 } for (int i=0; i<5; i++){ printf( "\nrow[%d] ", i ); for (int j=0; j<20; j++){ printf( "%-5d", grades[i][j] ); // 数据项宽度与标题项匹配 } } }
调整后的输出会完全对齐:
[ 0] [ 1] [ 2] [ 3] [ 4] [ 5] [ 6] [ 7] [ 8] [ 9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] row[0] 1 2 3 4 5 6 0 1 2 3 4 5 6 0 1 2 3 4 5 6 row[1] 1 2 3 4 5 6 0 1 2 3 4 5 6 0 1 2 3 4 5 6 row[2] 1 2 3 4 5 6 0 1 2 3 4 5 6 0 1 2 3 4 5 6 row[3] 1 2 3 4 5 6 0 1 2 3 4 5 6 0 1 2 3 4 5 6 row[4] 1 2 3 4 5 6 0 1 2 3 4 5 6 0 1 2 3 4 5 6
2. 处理多位数数据的对齐问题
如果数据包含多位数(如分数0-100),可以选择两种方式处理:
- 固定宽度法:根据数据的最大可能值设置宽度,比如0-100的分数用
%-4d(占4个字符宽度); - 动态适配法:先遍历数组找到最大值,计算其位数,再确定打印宽度,确保适配所有数据。
示例代码(动态计算宽度):
#include<stdio.h> int main(){ int grades[5][20] = { {95, 82, 73, 100, 55, 66, 0, 91, 82, 73, 64, 55, 46, 0, 31, 22, 13, 4, 5, 6 }, {10, 22, 33, 44, 55, 66, 0, 11, 22, 33, 44, 55, 66, 0, 11, 22, 33, 44, 55, 66 }, {1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6 }, {99, 88, 77, 66, 55, 44, 0, 33, 22, 11, 100, 99, 88, 0, 77, 66, 55, 44, 33, 22 }, {1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6 } }; // 找到数组中的最大值 int max_grade = 0; for(int i=0; i<5; i++){ for(int j=0; j<20; j++){ if(grades[i][j] > max_grade){ max_grade = grades[i][j]; } } } // 计算最大值的位数 int width = 0; int temp = max_grade; do{ width++; temp /= 10; }while(temp != 0); // 额外加1个空格作为间隔 width += 1; // 打印列标题,标题宽度与数据宽度匹配 printf( " " ); for (int i=0; i<20; i++) { printf( "%*s", width+1, "" ); // 用动态宽度适配 printf( "[%2d]", i ); } printf("\n"); // 打印数据 for (int i=0; i<5; i++){ printf( "\nrow[%d] ", i ); for (int j=0; j<20; j++){ printf( "%*d", width, grades[i][j] ); // 动态宽度打印数据 } } }
这段代码会根据数据中的最大值自动调整打印宽度,确保多位数数据也能完美对齐。
内容的提问来源于stack exchange,提问作者Osmium
相关产品推荐
相关产品推荐

