坑:C++ C 字符串乱码 返回char* 字符串乱码

博客探讨了在C++和C中遇到的字符串乱码问题,特别是涉及char*和char数组时。文章解释了两者之间的区别,char数组可以存储字符串并更改其内容,而char*则指向字符串常量,修改可能导致未定义行为。作者还分享了在函数中返回char*字符串时可能导致的问题,并提供了两个解决方案:使用strncpy()函数和memset()清空内存。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

字符串长了,导致乱码,

https://ask.csdn.net/questions/690176

问题char* 和char x[] 区别?

https://blog.csdn.net/yahohi/article/details/7427724

原因:没有清空垃圾,导致被污染。

char* 

char x[]

 

这里的char ch[]="abc";
表示ch 是一个足以存放字符串初值和空字符'/0'的一维数组,可以更改数组中的字符,但是ch本身是不可改变的常量。
char *pch = "abc";
那么pch 是一个指针,其初值指向一个字符串常量,之后它可以指向其他位置,但如果试图修改字符串的内容,结果将不确定。
     ______           ______      ______
ch: |abc\0 |    pch: | ◎----->  |abc\0 |
     ______           ______      ______

char chArray[100];
chArray[i] 等价于 *(chArray+i)
和指针的不同在于   chArray不是变量   无法对之赋值
另   事实上 i[chArray]  也等价于 *(chArray+i) ???(chArray+i 是个地址?)

*pp = "abc";

p[] = "abc";

*pp指向的是字符串中的第一个字符。

cout << pp; // 返回pp地址开始的字符串:abc

cout << p; // 返回p地址开始的字符串:abc

cout << *p; // 返回第一个字符:a

cout << *(p+1); // 返回第二个字符:b

cout << &p[1];// 返回从第二个字符开始的字符串:bc
---------------------  
原文:https://blog.csdn.net/yahohi/article/details/7427724  

 

 

 

原函数如下:

char*  StringConverter(const nsAString& aPara)
{
	nsAString::const_iterator start, end;
	aPara.BeginReading(start);
	aPara.EndReading(end);
	NS_ConvertUTF16toUTF8 cname(aPara);
	char* buffer = cname.BeginWriting();
	ADHOCLOG("aVoiceData  =%s ",buffer);
	return buffer;
}

在此函数中的输出值正确,问题出在return buffer 后衔接部分,

 

如何将char* 赋值给char数组?

解决办法参考:https://blog.csdn.net/hunter___/article/details/86617599

修改后:

void  StringConverter(const nsAString& aPara,char* result,int size)
{
	nsAString::const_iterator start, end;
	aPara.BeginReading(start);
	aPara.EndReading(end);
	NS_ConvertUTF16toUTF8 cname(aPara);
	char* buffer = cname.BeginWriting();
	strncpy(result,buffer,size);
	ADHOCLOG("aVoiceData  =%s ",buffer);
}

 

完美解决:

int16_t
//nsresult
MozAdhoc:: SendDataPri(const nsAString& aSrcAddr,const nsAString& aDesAddr,const nsAString& aData, int16_t aPri) 
{
	int size = 1024;
	ADHOCLOG("******* enter*********");
	void *handle = dlopen(dlib_path, RTLD_GLOBAL | RTLD_NOW); 
	if (handle == NULL) {
		fprintf(stderr, "%s", dlerror());
		ADHOCLOG(" dlerror########[ %s ]#####",dlerror());
	} else {
		ADHOCLOG("dlopen successed.");
		SendDataPri_ptr dl_func = (SendDataPri_ptr )dlsym(handle, "sendDataPri");
		char* aSrcAddr_cv= (char*)malloc(size+1);
		char* aDesAddr_cv= (char*)malloc(size+1);
		char* aData_cv= (char*)malloc(size+1);
		StringConverter(aSrcAddr,aSrcAddr_cv,size);
		StringConverter(aDesAddr,aDesAddr_cv,size);
		StringConverter(aData,aData_cv,size);
		int aPri_cv = aPri;
		dl_func(aSrcAddr_cv,aDesAddr_cv,aData_cv,aPri_cv);
		ADHOCLOG("%s, %s, %s, %d",aSrcAddr_cv,aDesAddr_cv,aData_cv,aPri_cv);
		free(aSrcAddr_cv);
		free(aDesAddr_cv);
		free(aData_cv);
		dlclose(handle);
	}

	return 233; 
	//return NS_OK; 
}//发送数据

 

总结:

大概有两个主要的解决办法:

1.strncpy()

函数返回char* 的解决方案

 

void func(char *result, int size)
{
       ...
      strncpy(result, "That' d be in the data segment, Bob", size);

}

buffer = malloc (size);
func(buffer);
...
free(buffer);

 

 

2.memset() 先清空内存

https://ask.csdn.net/questions/690176

#include <iostream>
#include <string.h>
#include <cstdio>
using namespace std;

void rep(char *str,char *fstr,char *rstr)
{
    int i,j,k,n,x,y=0,cnt=0;
    char sss[50];
    memset(sss, 0, 50); //加上这个
    n=strlen(fstr);
    x=strlen(rstr);
    for(i=0;str[i]!='\0';i++) {
        if(str[i]==fstr[0]) {
                k=1;
                j=i+1;
            while(j<i+n) {
                 if(str[j]==fstr[k]) {
                    j++;
                    k++;
                 }
                 else break;
            }
            if(j==i+n) {
               strcat(sss,rstr);
               cnt++;
               i=j-1;
               y=j+(x-n)*cnt-1;
            }
        }
        else sss[y]=str[i];
        y++;
    }

    sss[y]='\0';
    strcpy(str,sss);
}
int main()
{
    char str[50]="iffordowhileelsewhilebreak";
    char fstr[10]="while";
    char rstr[10]="struct";
    /*gets(str);
    gets(fstr);
    gets(rstr);*/
    rep(str,fstr,rstr);
    cout<<str<<endl;
    return 0;
}

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值