我想在C语言中测试数组,因为我刚开始学习这门语言。以下是我的代码:
#include <stdio.h>
main(){
int i,t;
char orig[5];
for(i=0;i<=4;i++){
orig[i] = '.';
}
printf("%s\n", orig);
}
这是我的输出结果:
.....�
这就是它的原意。那些神秘的字符是什么?我做错了什么吗?
我想在C语言中测试数组,因为我刚开始学习这门语言。以下是我的代码:
#include <stdio.h>
main(){
int i,t;
char orig[5];
for(i=0;i<=4;i++){
orig[i] = '.';
}
printf("%s\n", orig);
}
这是我的输出结果:
.....�
%s
与printf()
一起使用时需要一个指向字符串的指针,也就是指向以空字符结尾的字符数组的初始元素的指针。你的数组没有以空字符结尾。
因此,在寻找终止的空字符时,printf()
会越界,随后引发未定义行为。
如果要将其用作字符串,则必须将数组以空字符结尾。
引用:C11
,第§7.21.6.1章,(重点强调)
s
如果没有l长度修饰符,则参数应该是指向字符类型数组的初始元素的指针。280)从数组中写入的字符最多到(但不包括)终止的空字符。如果指定了精度,则最多只写入那么多个字节。如果未指定精度或精度大于数组的大小,则该数组必须包含空字符。
快速解决方法:
char orig[6];
。orig[i] = '\0';
然后,打印结果。
char orig[5];//creates an array of 5 char. (with indices ranging from 0 to 4)
|?|?|?|0|0|0|0|0|?|?|?|?|
| ^memory you do not own (your mysterious characters)
^start of orig
for(i=0;i<=4;i++){ //attempts to populate array with '.'
orig[i] = '.';
|?|?|?|.|.|.|.|.|?|?|?|?|
| ^memory you do not own (your mysterious characters)
^start of orig
这将导致一个非空终止字符的数组,如果在期望C字符串的函数中使用,将会产生未定义的行为。 C字符串必须包含足够的空间来允许空终止符的存在。请更改您的声明以适应此要求。
char orig[6];
...
for(i=0;i<=4;i++){
orig[i] = '.';
}
orig[i] = 0;
|?|?|?|.|.|.|.|.|0|?|?|?|
| ^memory you do not own
^start of orig
< p > 注意: 因为空终止符会产生C字符串,使用它的函数知道如何解释其内容(即没有未定义的行为),并且您神秘的字符被阻止。
数组和字符数组之间有区别。在C语言中,可以将字符数组视为数组的一种特殊情况,其中每个元素都是char
类型,并且该数组应以字符null
(ASCII值0
)结尾。
printf()
中的%s
格式说明符需要一个指向以null
字符结尾的字符数组的指针。您的数组没有以null结尾,因此printf
函数会超出您分配的5个字符并打印后面的垃圾值('.')。
要解决问题,您需要静态分配大小比要存储的字符多一个的字符数组。在您的情况下,大小为6的字符数组将起作用。
#include <stdio.h>
int main(){
int i,t;
char orig[6]; // If you want to store 5 characters, allocate an array of size 6 to store null character at last position.
for (i=0; i<=4; i++) {
orig[i] = '.';
}
orig[5] = '\0';
printf("%s\n", orig);
}
sizeof
这样的操作符在函数内部不起作用,而且sizeof
将返回您机器上指针的大小)。这就是为什么像memcpy
、memset
这样的函数需要额外的参数来说明数组的大小(或者您想要操作的长度)。
然而,使用字符数组,函数可以通过寻找特殊字符(null
字符)来确定数组的大小。
#include <stdio.h>
main()
{
int i,t;
char orig[6];
for(i=0;i<=4;i++){
orig[i] = '.';
}
orig[i] = '\0';
printf("%s\n", orig);
}
\0
是什么,我强烈建议您查看ASCII表格(https://www.asciitable.com/)。orig[i] = '\0';
实际上有一个偏差。 - Sourav Ghosh\0
是表示为 NUL '\0'(空字符)
的字符。 - Gangai Johannprintf
需要以任何内存位置的起始指针为参数,本例中为数组,并打印直到遇到\0
字符。这种类型的字符串称为null
终止字符串。
因此,请在末尾添加\0
并输入字符直到(数组大小-2),如下所示:
main(){
int i,t;
char orig[5];
for(i=0;i<4;i++){ //less then size of array -1
orig[i] = '.';
}
orig[i] = '\0'
printf("%s\n", orig);
}