注册 登录
编程论坛 C++教室

哪位大哥帮帮忙看看怎么改下 字符串复制问题

oicq 发布于 2010-09-25 16:49, 1532 次点击
题目:

已知strcpy 函数的原型是:

char *strcpy(char *strDest, const char *strSrc);

其中strDest 是目的字符串,strSrc 是源字符串。不调用C++/C 的字符串库函数,请编写函数 strcpy

下面是我写的代码
程序代码:
#include<iostream.h>
char *strcpy(char* strDest ,const char* strSrc);
void main ()
{
    char adress[]="String Copy";
    char* Dst="Why";
    strcpy(Dst,adress);
    cout<<Dst<<endl;   
}
char *strcpy(char* strDest ,const char* strSrc)
{
    if ( strDest == NULL || strSrc == NULL )
    {   
        cout<<"strDest == NULL || strSrc == NULL"<<endl;   
    }
   
    while ( (*strDest++ = *strSrc++ ) != '\0' )   
    {
         ;
    }
    return strDest;
}

为什么编译连接都没问题    运行时就报错
15 回复
#2
kspliusa2010-09-25 17:11
char* Dst="Why";要申请空间
#3
zgxyz20082010-09-25 17:26
初步看一下,程序的思路有问题:strDest是局部指针变量,而子函数是不能返回局部指针变量和引用类型的,因为在子函数结束时,会释放掉所占内存;while语句中的赋值方式是错误的,指针变量是不能那样赋值的。最好应该重新考虑下方法。

[ 本帖最后由 zgxyz2008 于 2010-9-25 17:28 编辑 ]
#4
mxs8102010-09-25 17:52
应该首先考虑两个字符串中字符的个数,防止越界拷贝~~
#5
m21wo2010-09-25 18:38
#include<iostream>
#include<cassert>
using namespace std;
char* strcpy1(char* strDest , const char* strSrc);
void main ()
{
    char* adress="String Copy";
    int length=strlen(adress);
    char* Dst="Why";
    Dst=new char[length+1];  // 确保Dst的空间比adress 大
    strcpy1(Dst,adress);
    cout<<Dst<<endl;   
}
char* strcpy1(char* strDest ,const char* strSrc)
{
    assert((strDest!=NULL)&&(strSrc!=NULL));
    char* temp=strDest;
    while(*strSrc!= '\0')
    {
        *strDest++ = *strSrc++;
    }
    *strDest='\0';  //保证strDest 它是字符串!!!
    return temp;
}
ok 啦!
#6
oicq2010-09-25 18:43
   一上来看到这么多人 帮忙  嘿嘿 谢谢啦          
#7
2010-09-26 10:49
int *p是说p是指向int型的指针  char* p怎么解释?
#8
幽园香客2010-09-26 11:22
以下是引用kspliusa在2010-9-25 17:11:24的发言:

char* Dst="Why";要申请空间

楼上正解
#9
无名可用2010-09-26 14:17
char* Dst="Why";句中Dst指向的是常量,对常量进行修改会引起运行错误的
#10
yangang22010-09-26 15:11
应该改为:
#include<iostream.h>
char *strcpy(char* strDest ,const char* strSrc);
void main ()
{
    char adress[]="String Copy";
    char  Dst[99]="Why";//不能写为char *Dst="Why";
    strcpy(Dst,adress);
    cout<<Dst<<endl;   
}
char *strcpy(char* strDest ,const char* strSrc)
{
    if ( strDest == NULL || strSrc == NULL )
    {   
        cout<<"strDest == NULL || strSrc == NULL"<<endl;   
    }
   
    while ( (*strDest++ = *strSrc++ ) != '\0' )   
    {
         ;
    }
    return strDest;
}
为什么不能将char  Dst[99]="Why";写为char *Dst="Why";因为字符串的存储形式有两种,一种是字符数组,一种是字符指针,但这两种是由差别的,字符数组可以对存储的字符串进行读写操作,而字符指针即你所定义的char *Dst="Why";只能进行读操作,不能进行写操作。当你尝试语句 while ( (*strDest++ = *strSrc++ ) != '\0' )   时就造成了致命错误,因为strDest接受的是指针Dst,而该指针所指向的字符串是不能进行写操作的。所以应该定义为数组,且数组要足够容纳被复制的字符串。

为了检验你是否懂了,可以在看看下面的论述:
利用指针来处理字符串时,要注意指针所指向的字符串是字符串常量还是存储在字符数组中的字符串,因为这两种字符串在处理时有很大差别。当指针指向的字符串是字符数组中的字符串时,可以用该指针对所指向的存储单元进行读写。当指针指向的字符串是字符串常量时,则只能用该指针对指向的存储单元进行读取。不能进行改写,因为C语言没有对这种情况进行定义。如果利用指向字符串常量的指针对它所值的存储单元进行改写,这个程序在编译时能够通过,在程序运行时可能就会出错。如:
#include"stdio.h"
main()
{
    char *s1="good morning!";
    char *s2="good afternoon!";
    char *p1,*p2;
    printf("before copying:\ns1:%s;\ns2:%s;\n",s1,s2);
    p1=s1;
    p2=s2;
    while(*p2++=*p1++);
    printf("after copying:\ns1:%s;\ns2:%s;\n",s1,s2);
}

为了避免这种错误,应改为以下形式:
#include"stdio.h"
main()
{
    char s1[]="good morning!";
    char s2[]="good afternoon!";
    char *p1,*p2;
    printf("before copying:\ns1:%s;\ns2:%s;\n",s1,s2);
    p1=s1;
    p2=s2;
    while(*p2++=*p1++);
    printf("after copying:\ns1:%s;\ns2:%s;\n",s1,s2);
}

对上面循环体为空语句的while循环的理解:可将其写成比较繁琐的形式
    while ((*p2=*p1)!='\0')
{
p2++;
p1++;
}

这段程序的含义是将字符串s1的第一个字符赋值给字符数组s2的第一个元素,然后判断赋值后的结果,也就是*p1是否不等于’\0’。如果*p1不等于’\0’,则执行循环体使指针p1和p2指向字符串的下一个字符。然后继续赋值,直到s1的结尾字符’\0’赋给字符串s2为止,才停止循环。这时已经将字符串s1的所有字符赋值给s2了。由于字符’\0’的值等于0,因此,表达式(*p2=*p1)!='\0'等价于(*p2=*p1)!=0,(对比一个变量时如while(*p2!=’\0’)类似于两个变量时的情况,即可以省略’\0’)而表达式(*p2=*p1)!=0又等价于*p2=*p1,所以上面这段程序又等价于:
    while (*p2=*p1)
{
p2++;
p1++;
}

又因为可以将指针p1和p2的自增运算放于表达式中,所以上面代码进一步简化为:
while(*p2++=*p1++);
当然这样简化后的唯一区别在于循环结束时,指针p1和p2指向的是’\0’后面的哪个存储单元,但这不影响程序要完成的功能。


#11
2010-09-27 00:41
回复 10楼 yangang2
char *strcpy(char* strDest ,const char* strSrc); 为什么这个拷贝函数的参数是这样的   char* 和char *之间的差别是什么?这个函数里三个*的我不懂 求解!
#12
ToBeOOP2010-09-27 06:12
额...这个程序不能防止拷贝超出界限...
#13
ToBeOOP2010-09-27 06:19
程序代码:
#include <iostream>
using std::cout;
using std::endl;
char *strcpy(char* strDest ,const char* strSrc);
int main ()
{
    char adress[ ]="String Copy";
    char Dst [ ]="Why fdfefdsfefsdf";
    cout<<strcpy(Dst,adress)<<endl;
    system ("Pause");
    return 0;
}
char *strcpy(char* strDest ,const char* strSrc)
{
    if ( *strDest == NULL || *strSrc == NULL )
    {  
        cout<<"strDest == NULL || strSrc == NULL"<<endl;  
    }
    while ( (*strDest++ = *strSrc++ ) != '\0' )  
    {
         ;
    }
    return strDest;
}

主要原因是目标字符串的长度没有源字符串的长.....
#14
寒风中的细雨2010-09-27 18:19
#include<iostream.h>
#include <malloc.h>
char *strcpy(char* strDest ,const char* strSrc);
void main ()
{
    char adress[]="String Copy woieuoifji";
    char *Dst = 0;
    Dst = strcpy(Dst,adress);
    cout<<Dst<<endl;   
}
char *strcpy(char* strDest ,const char* strSrc)
{
    int i = 0;
    if ( strSrc == NULL )
    {   
        cout<<"strDest == NULL || strSrc == NULL"<<endl;   
    }
   else
   {
       strDest = (char *) malloc (2*sizeof(char));
       *(strDest+1)='\0';
   }
    while ( *strSrc != '\0' )   
    {
        *(strDest+i) = *strSrc++;
        ++i;
        strDest = (char *) realloc (strDest, (i+1)*sizeof(char));
        *(strDest+i) = '\0';
    }
    return strDest;
}
#15
laoyang1032010-09-30 20:19
你要确保你向拷贝函数传递的参数的生存期,也就是要把他放到堆中,不能让系统默认放在栈中 这样函数执行完了就会被释放掉
#16
lyj2010lyj2010-09-30 20:53
以下是引用fairy_tail在2010-9-26 10:49:30的发言:

int *p是说p是指向int型的指针  char* p怎么解释?
说的在理
1