简体   繁体   English

有关将char数组复制到char指针的基本C问题

[英]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. 其次, pstrstr指向相同的内存,因此您的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM