当我刚刚开始学习这门语言时,我想用 C 上的数组来测试一下。这是我的代码:
#include <stdio.h>
main(){
int i,t;
char orig[5];
for(i=0;i<=4;i++){
orig[i] = '.';
}
printf("%s\n", orig);
}
这是我的输出:
.....�
正是这样。那些神秘人物是什么?我做错了什么?
%swithprintf()需要一个指向 string的指针,即指向空终止字符数组的初始元素的指针。您的数组不是以空值结尾的。
因此,在搜索终止的空字符时,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
这会产生一个非空终止的 char 数组,如果在需要 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
注意:因为空终止会导致 C 字符串,使用它的函数知道如何解释其内容(即没有未定义的行为),并且您的神秘字符被搁置了。
数组和字符数组是有区别的。您可以认为字符数组是数组的一种特殊情况,其中每个元素都是charC 中的类型,并且该数组应以字符null( ) 结束(终止ASCII value 0)。
%s格式说明符printf()需要一个指向以字符结尾的字符数组的指针null。您的数组不是以空值结尾的,因此,printf函数超出了您分配的 5 个字符,并在您的第 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字符)来确定数组的大小。
您需要在字符串末尾添加一个NUL字符 ( )。\0
#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/)。
祝你好运
prinftf获取任何内存位置的起始指针,在这种情况下为数组并打印直到遇到\0字符。这些类型的字符串称为null终止字符串。
所以请\0在末尾添加 a 并输入字符直到(数组大小 - 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);
}