在我刚开始学习语言时,我想用C上的数组测试事物。这是我的代码:
#include <stdio.h>
main(){
int i,t;
char orig[5];
for(i=0;i<=4;i++){
orig[i] = '.';
}
printf("%s\n", orig);
}
这是我的输出:
.....�
就是这样。那些神秘人物是什么?我做错了什么?
答案 0 :(得分:7)
%s
的 printf()
需要一个指向 string 的指针,即,指向以空终止的字符数组的初始元素的指针。您的数组不是以null结尾的。
因此,printf()
在搜索终止的空字符时超出范围,随后调用undefined behavior。
如果要将其用作 string ,则必须对数组进行空终止。
语录:C11
,第§7.21.6.1章,(强调我的)
s
如果不存在l长度修饰符,则参数应为指向字符类型数组的初始元素的指针。 280)数组中的字符为 写入(但不包括)终止空字符。如果 指定了精度,但写入的字节数不超过该字节数。 如果 没有指定精度或大于数组的大小,数组应 包含空字符。
快速解决方案:
char orig[6];
。orig[i] = '\0';
然后打印结果。
答案 1 :(得分:4)
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
这将导致一个非null终止的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字符串,所以使用它的函数知道如何解释其内容(即没有未定义的行为),并且您的神秘人物被拒之门外。 >
答案 2 :(得分:2)
数组和字符数组之间有区别。您可以认为字符数组是数组的一种特殊情况,其中每个元素在C中的类型为char
,并且该数组应以字符null
(ASCII value 0
)结尾(终止)
%s
的 printf()
格式说明符期望一个指向以null
字符结尾的字符数组的指针。您的数组不是以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
字符)来确定数组的大小。
答案 3 :(得分:1)
您需要在字符串的末尾添加一个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/)。
祝你好运
答案 4 :(得分:1)
prinftf
获取任何内存位置的起始指针,在这种情况下为数组并打印直到遇到\0
字符。这些类型的字符串称为null
终止的字符串。
因此,请在末尾添加\0
并输入直到(array-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);
}