根据这个: strcpy vs strdup, strcpy 可以通过循环实现,他们使用了这个while(*ptr2++ = *ptr1++)
.我尝试做类似的事情:
#include <stdio.h>
#include <stdlib.h>
int main(){
char *des = malloc(10);
for(char *src="abcdef ";(*des++ = *src++););
printf("%sn",des);
}
但这不会打印任何内容,也没有错误。出了什么问题?
非常感谢您的回答,我已经玩了一点,并决定如何最好地设计循环以查看复制如何逐字节进行。这似乎是最好的:
#include <stdio.h>
#include <stdlib.h>
int main(){
char *des = malloc(7);
for(char *src="abcdef", *p=des; (*p++=*src++); printf("%sn",des));
}
在此循环中
for(char *src="abcdef ";(*des++ = *src++););
正在更改目标指针des
。因此,在循环之后,它不会指向复制字符串的开头。
请注意,显式终止零字符' '
在字符串文本中是多余的。
循环可以如下所示
for ( char *src = "abcdef", *p = des; (*p++ = *src++););
然后在循环之后
puts( des );
和
free( des );
您可以编写类似于strcpy
以下方式的单独函数
char * my_strcpy( char *des, const char *src )
{
for ( char *p = des; ( *p++ = *src++ ); );
return des;
}
并称它为像
puts( my_strcpy( des, "abcdef" ) )'
free( des );
您正在递增des
因此在循环结束时自然地指向字符串的末尾,打印它相当于未定义的行为,您必须将其带回des
的开头。
#include <stdio.h>
#include <stdlib.h>
int main(){
int count = 0;
char *des = malloc(10);
if(des == NULL){
return EXIT_FAILURE; //or otherwise handle the error
}
// ' ' is already added by the compiler so you don't need to do it yourself
for(char *src="abcdef";(*des++ = *src++);){
count++; //count the number of increments
}
des -= count + 1; //bring it back to the beginning
printf("%sn",des);
free(dest); //to free the allocated memory when you're done with it
return EXIT_SUCCESS;
}
或者创建一个指向des
开头的指针并打印它。
#include <stdio.h>
#include <stdlib.h>
int main(){
char *des = malloc(10);
if(des == NULL){
return EXIT_FAILURE; //or otherwise handle the error
}
char *ptr = des;
for(char *src="abcdef";(*des++ = *src++);){} //using {} instead of ;, it's clearer
printf("%sn",ptr);
free(ptr) // or free(dest); to free the allocated memory when you're done with it
return EXIT_SUCCESS;
}
printf("%sn",des);
是未定义的行为(UB(,因为它尝试从写入分配内存的字符串末尾开始打印。
复制字符串
保存原始指针,检查它并在完成后释放。
const char *src = "abcdef "; // string literal here has 2 ending ` `,
char *dest = malloc(strlen(src) + 1); // 7
char *d = dest;
while (*d++ = *src++);
printf("%sn", dest);
free(dest);
复制字符串文本
const char src[] = "abcdef "; // string literal here has 2 ending ` `,
char *dest = malloc(sizeof src); // 8
for (size_t i = 0; i<sizeof src; i++) {
dest[i] = src[i];
}
printf("%sn", dest);
free(dest);
你只需要记住原来分配的指针。
不要在主中编程。使用函数。
#include <stdio.h>
#include <stdlib.h>
size_t strSpaceNeedeed(const char *str)
{
const char *wrk = str;
while(*wrk++);
return wrk - str;
}
char *mystrdup(const char *str)
{
char *wrk;
char *dest = malloc(strSpaceNeedeed(str));
if(dest)
{
for(wrk = dest; *wrk++ = *str++;);
}
return dest;
}
int main(){
printf("%sn", mystrdup("asdfgfd"));
}
甚至更好
size_t strSpaceNeedeed(const char *str)
{
const char *wrk = str;
while(*wrk++);
return wrk - str;
}
char *mystrcpy(char *dest, const char *src)
{
char *wrk = dest;
while((*wrk++ = *src++)) ;
return dest;
}
char *mystrdup(const char *str)
{
char *wrk;
char *dest = malloc(strSpaceNeedeed(str));
if(dest)
{
mystrcpy(dest, str);
}
return dest;
}
int main(){
printf("%sn", mystrdup("asdfgfd"));
}
分配目标缓冲区des
并将源字符串正确复制到适当的位置。但是,由于您为复制的每个字符递增des
,因此您已将des
从字符串的开头移动到末尾。当您打印结果时,您正在打印最后一个字节,即 nil 终止,它是空的。
相反,您需要保留指向字符串开头的指针,以及指向您复制的每个字符的指针。
与原始来源的最小变化是:
#include <stdio.h>
#include <stdlib.h>
int main(){
char *des = malloc(10);
char *p = des;
for(char *src="abcdef";(*p++ = *src++););
printf("%sn",des);
}
因此p
是指向下一个目标字符的指针,并沿字符串移动。但是您打印的最后一个字符串是des
,从分配开始。
当然,您还应该为des
分配strlen(src)+1
字节。并且没有必要以 null 终止字符串文字,因为这将由编译器为您完成。
但这不会打印任何内容,也没有错误。出了什么问题?
des
在执行(*des++ = *src++)
后不再指向字符串的开头。实际上,des
指向NUL
字符之后的一个元素,该元素将终止字符串。
因此,如果要使用printf("%sn",des)
打印字符串,它将调用未定义的行为。
您需要将"start"指针的地址值(指向分配的内存块的第一个char
对象(存储到临时的"持有者"指针中。有多种可能的方法。
#include <stdio.h>
#include <stdlib.h>
int main (void) {
char *des = malloc(sizeof(char) * 10);
if (!des)
{
fputs("Error at allocation!", stderr);
return 1;
}
char *tmp = des;
for (const char *src = "abcdef"; (*des++ = *src++) ; );
des = temp;
printf("%sn",des);
free(des);
}
选择:
#include <stdio.h>
#include <stdlib.h>
int main (void) {
char *des = malloc(sizeof(char) * 10);
if (!des)
{
fputs("Error at allocation!", stderr);
return 1;
}
char *tmp = des;
for (const char *src = "abcdef"; (*des++ = *src++) ; );
printf("%sn", tmp);
free(tmp);
}
或
#include <stdio.h>
#include <stdlib.h>
int main (void) {
char *des = malloc(sizeof(char) * 10);
if (!des)
{
fputs("Error at allocation!", stderr);
return 1;
}
char *tmp = des;
for (const char *src = "abcdef"; (*tmp++ = *src++) ; );
printf("%sn", des);
free(des);
}
<小时 />旁注:
"abcdef "
- 不需要显式