[英]Basic C question on copying char arrays to char pointers
I have some doubts in basic C programming. 我对基本C编程有一些疑问。
I have a char array and I have to copy it to a char pointer. 我有一个char数组,我必须将其复制到char指针。 So I did the following: 所以我做了以下事情:
char a[] = {0x3f, 0x4d};
char *p = a;
printf("a = %s\n",a);
printf("p = %s\n",p);
unsigned char str[] = {0x3b, 0x4b};
unsigned char *pstr =str;
memcpy(pstr, str, sizeof str);
printf("str = %s\n",str);
printf("pstr = %s\n",pstr);
My printf statements for pstr and str get appended with the data "a". 我对pstr和str的printf语句附加了数据“ a”。 If I remove memcpy I get junk. 如果删除memcpy,我会成为垃圾。 Can some C Guru enlighten me? 某些C大师可以启发我吗?
Firstly, C strings (the %s
in printf
) are expected to be NUL-terminated. 首先,C字符串( printf
的%s
)应为NUL终止。 You're missing the terminators. 您错过了终结者。 Try char a[] = {0x3f, 0x4d, 0}
(same goes for str
). 尝试使用char a[] = {0x3f, 0x4d, 0}
( str
)。
Secondly, pstr
and str
point to the same memory, so your memcpy
is a no-op. 其次, pstr
和str
指向相同的内存,因此您的memcpy
是no-op。 This is a minor point compared to the first one. 与第一个相比,这是次要的一点。
添加一个空终止符,因为这是您期望的printf:
char a[] = {0x3f, 0x4d, '\0'};
The standard way C strings are represented is that in memory, they are a sequence of non-zero bytes representing the characters, followed by a zero (or NULL) byte. C字符串的标准表示方式是在内存中,它们是表示字符的一系列非零字节,后跟一个零(或NULL)字节。 You should declare: 您应该声明:
char a[] = {0x3f, 0x4d, 0};
When you assign a string pointer (as in unsigned char *pstr = str;
) both pointers point to the same memory area, and thus the same characters. 当您分配一个字符串指针(如unsigned char *pstr = str;
)时,两个指针都指向相同的存储区,因此指向相同的字符。 There is no need to copy the characters. 无需复制字符。
When you do need to copy characters, you should be using strlen()
, the sizeof()
operator returns the number of bytes its argument uses in memory. 当确实需要复制字符时,应该使用strlen()
, sizeof()
运算符返回其参数在内存中使用的字节数。 sizeof(pointer)
is the number of bytes the pointer uses, not the length of the string. sizeof(pointer)
是指针使用的字节数,而不是字符串的长度。 You find the length of a string (ie the number of bytes it occupies in memory) with the strlen()
function. 您可以使用strlen()
函数找到字符串的长度(即,它在内存中占用的字节数strlen()
。 Also, there are standard functions to copy C strings. 另外,还有一些标准函数可以复制C字符串。 You should rely on those to do the right thing: 您应该依靠那些来做正确的事情:
strcpy(pstr, str);
printf
's %s
expects a 0-terminated string, your strings aren't. printf
的%s
期望以0结尾的字符串,但您的字符串不是。 The uninitialized memory following your arrays may however happen to start with a 0-byte, in which case your code will appear to be correct - it still isn't. 但是,数组之后的未初始化内存可能恰好以0字节开头,在这种情况下,您的代码似乎是正确的-仍然不是。
You're declaring an array "str", then pointing to it with pstr. 您要声明一个数组“ str”,然后使用pstr指向它。 Note that you have no null-terminating character, so after using memcpy you copy the block to itself with no null terminator, as a string requires . 请注意,您没有空终止符,因此在使用memcpy之后,您需要将一个无空终止符的块复制到自身,这是字符串要求 。 Thus, printf can't find the end of the string and continues printing until it finds a 0 (or '\\0' in character terms) 因此,printf找不到字符串的末尾并继续打印,直到找到0(或用字符表示的'\\ 0')为止
Agreed. 同意。 You'll have to add a null byte at the end of your array of chars. 您必须在字符数组的末尾添加一个空字节。
char a[] = {0x3f, 0x4d, '\0'};
The reason being is that you're creating a string without declaring where it actually ends. 原因是您在创建字符串时未声明其实际结束位置。 Your memcpy() function copies *str to *pstr and automatically adds a null byte for you, which is why it works. 您的memcpy()函数将* str复制到* pstr并自动为您添加一个空字节,这就是它起作用的原因。
Without memcpy() there the string never knows when to end, so it reaches into subsequent memory addresses and returns whatever random values are stored there. 如果没有memcpy(),该字符串将永远不知道何时结束,因此它会到达后续的内存地址并返回存储在那里的任何随机值。 When you're creating a string out of characters, always remember to end it with a null byte. 当使用字符创建字符串时,请始终记住以空字节结尾。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.