C语言 字符串常见问题总结

字符串的操作时C中非常常见的,但是稍不注意就会出现错误,而且这种错误往往时运行时才会崩溃(段错误),让你的程序很难调试。下面就说说常见的几种错误


1.为字符串指针赋值,后修改

	char q[10] = {'I',' ','a','m',' ','h','a','p','p','y'};
	char *p = "I am happy";
	strcat(p,q);

这是因为“I am happy”是字符串常量,对于常量操作肯定出错!另外p只是将 “I am happy”的首地址 赋值给了 指针p,在程序栈中并没有“I am happy”这些数据,只有“I am happy”的首地址,所以可想而知sizeof(p)应该是4,也就是“I am happy”首地址长度。

但是

	char q[10] = "I am happy";
	char *p = "I am happy";
	q[0] = 'G';
	strcat(p,q);
	int i1=sizeof(q);
	int i2=sizeof(p);
	printf("%d\n",i1);
	printf("%d\n",i2);
sizeof(q)就是10,也就是说在栈中分配了内存,并存储相应内容。所以就可以更改字符串数组中的内容,因为这时更改的是栈中的内容。
2.strcpy和memcpy操作

这两个函数是非常常用的函数,具体功能就不介绍了,看看错误会是哪些

	char *p;
	char *s = "asdasd";
	strcpy(p,s);
这时运行程序就会段错误,为什么呢,之前我一直以为是因为s是字符串常量,而看看strcpy的源码

char* strcpy(char* des,const char* source)
 {
 char* r=des;
 while((*(des++)=*(source++))!='\0');
 return r;
 }
你会不会以为是因为source++改变了字符串常量,所以导致了段错误?

其实这个错误很简单,strcpy的源码并没有更改s字符串,看这里,参数类型:const char* source
也就是说strcpy并不会改变source变量!
原因出在p没有分配内存。。是不是知道真相眼泪掉下来?

另外在使用memcpy的时候注意添加‘\0’

3.strcat
strcat没有什么值得注意的,主要是strcat并不需要添加‘\0’,看源码

//将源字符串加const,表明其为输入参数
char* strcat(char* strDest , const char*s trSrc)
{
    //后文return address,故不能放在assert断言之后声明address
    char* address=strDest;
    assert( (strDest!=NULL)&&(strSrc!=NULL) );//对源地址和目的地址加非0断言
    while(*strDest)//是while(*strDest!=’\0’)的简化形式
    {
        //若使用while(*strDest++),则会出错,因为循环结束后strDest还会执行一次++,
        //那么strDest将指向'\0'的下一个位置。/所以要在循环体内++;因为要是*strDest最后指
        //向该字符串的结束标志’\0’。
        strDest++;
    }
 
    while(*strDest++=*strSrc++)
    {
        NULL;//该循环条件内可以用++,
    }//此处可以加语句*strDest=’\0’;无必要
    return address;//为了实现链式操作,将目的地址返回
}
在while最后会赋值 ‘\0’,所以不需要手动在添加~

关于字符串的知识还是很多的,暂时遇到这些,再结合栈的知识理解之。

以后遇到再加吧~

你可能感兴趣的:(C)