内存重叠之strncpy---指针踩雷

前几天帮一个同学改代码,苦苦寻思了半天终于发现问题所在:内存重叠,因此写下这篇文章以作警示。

程序作用:输入字符串,输入右移位数n,然后输出字符串循环右移n位的结果。

例如,输入abcdefg,在输入2,则结果应为fgabcde。

以下是源代码

void main()
{
	char str[200],ch[200];
	int len,n,i;	
	char *p,*q;	
	printf("输入字符串:");	
	gets(str);
	printf("右移的位数为:");
	scanf("%d",&n);

	p=str;
	q=p+strlen(p)-1;
	len=strlen(p);
	for(i=n;i>0;i--)//取出倒数n个字符
	{	
		ch[i-1]=*q;
		q--;
	}
		
	strncpy(p+n,p,len-n);//正是此处出了问题
	p[a]='\0';
	
	for(i=0;i<n;i++)
		p[i]=ch[i];
	printf("调整后的字符串为:%s\n",p);
	
}

同学的思路是,先把后面n位字符保存到数组ch中,然后再把p向后复制(len-n)位到p+n中,再把数组ch中的字符复制回p的前n位。

但是,此处出了一个内存重叠的问题,书上的代码是把后面的字符往前移没有出现错误,但是把字符从前面往后移的时候就会出现问题。(从后往前是否真的不会出现问题?我也不太确定。。)

以下是解决方案:

#include<stdio.h>
#include<string.h>

void main()
{
	char str[200],ch[200];
	int len,n;	
	printf("输入字符串:");	
	gets(str);
	printf("右移的位数为:");
	scanf("%d",&n);
	len=strlen(str);//把a改成len,长度
	
	strcpy(ch, str+len-n);
        strcpy(ch+n, str);
        *(ch+len)  = '\0';
        strcpy(str, ch);
	
	printf("调整后的字符串为:%s\n",str);
	
}

封装之后:

void LoopMove(char *str, int n)
{
    int len = strlen(str);
    char tmp[NUM];
    strncpy (tmp, str+len-n, n);
    strncpy (tmp+n, str, len-n);
    *(tmp+len)  = '\0';
    strncpy (str, tmp, len);
}



扫描二维码关注公众号,回复: 2679088 查看本文章


猜你喜欢

转载自blog.csdn.net/qwe641259875/article/details/80633157