为何二维字符数组用%s打印与逐个字符打印输出结果不同?
问题:二维数组用
printf("%s")打印格式异常的原因 想要创建一个可在指定[y][x]位置修改字符的表格状二维数组,编写了如下C语言代码填充数组:
int main() { int DIMENSION[2] = { 5, 5 }; //create buffer [multidimensional array] char buffer[DIMENSION[1]][DIMENSION[0]]; int x, y; // fill buffer for (y = 0; y < DIMENSION[1]; y++) { for (x = 0; x < DIMENSION[1]; x++){ printf("%d%d\n", y, x); buffer[y][x] = 'o'; } } // manipulate the buffer here // draw the buffer for (int i = -1; i < DIMENSION[1]; i++) { printf("%s\n", buffer[i]); } return 0; }
使用printf("%s")打印每行时,输出结果为:
ooooooooooooooooooooooooo oooooooooooooooooooo ooooooooooooooo oooooooooo ooooo
而采用逐个字符打印的方式:
for (y = 0; y < DIMENSION[1]; y++) { for (x = 0; x < DIMENSION[1]; x++) { printf("%c", buffer[y][x]); } printf("\n"); }
则能输出每行5个'o'的正确格式:
ooooo ooooo ooooo ooooo ooooo
请问这一现象的原因是什么?
原因分析
核心问题出在**printf("%s")的工作机制**上:
- C语言中,
printf("%s")要求输出的字符序列必须以空字符'\0'作为结束标记,否则它会从数组起始地址开始,持续读取内存中的字符,直到碰巧遇到'\0'才停止。 - 你定义的二维数组
buffer[5][5],每个行数组只有5个元素,全部被填充为'o',没有多余空间存放'\0'。这就导致printf("%s")打印时会越界读取数组后面的内存内容,直到找到'\0'为止。 - 从输出结果能看出,每行对应的内存区域里,
'\0'的位置逐行提前,所以打印的字符数越来越少。 - 而逐个字符打印的方式,严格控制了只打印5个
'o'就换行,不会越界读取内存,因此格式完全符合预期。
可选解决办法
- 定义数组时给每行多留一个位置存储终止符:
char buffer[DIMENSION[1]][DIMENSION[0]+1]; // 填充完'o'后添加终止符 for (y = 0; y < DIMENSION[1]; y++) { buffer[y][DIMENSION[0]] = '\0'; } - 或者用指定长度的打印方式,无需依赖
'\0':printf("%.*s\n", DIMENSION[0], buffer[i]);
内容的提问来源于stack exchange,提问作者Suikyoo
相关产品推荐
相关产品推荐

