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

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

字符串长了,导致乱码,

https://ask.youkuaiyun.com/questions/690176

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

https://blog.youkuaiyun.com/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.youkuaiyun.com/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.youkuaiyun.com/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.youkuaiyun.com/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;
}

 

 

 

 

 

 

 

<think>我们被要求输出字符串char*)的示例代。根据引用[1]和引用[2],我们知道: - 使用printf函数和%s格式符可以输出字符串。 - 字符串可以用char*指针指向。 因此,我们可以通过以下步骤实现: 1. 定义一个字符串(可以用字符数组或字符指针指向字符串字面量)。 2. 使用printf函数配合%s格式符输出。 注意:字符串字面量存储在只读区域,如果试图修改会导致未定义行为(引用[3])。如果我们需要修改字符串,应该使用字符数组。 示例代: ```c #include <stdio.h> int main() { // 示例1:使用字符指针指向字符串字面量(不可修改) char *str1 = "Hello, World!"; printf("%s\n", str1); // 输出:Hello, World! // 示例2:使用字符数组(可修改) char str2[] = "Hello, C Language!"; printf("%s\n", str2); // 输出:Hello, C Language! // 示例3:动态分配字符串 char *str3 = (char *)malloc(20 * sizeof(char)); if (str3 == NULL) { printf("内存分配失败\n"); return 1; } strcpy(str3, "Dynamic String"); printf("%s\n", str3); // 输出:Dynamic String free(str3); // 释放动态分配的内存 return 0; } ``` 注意事项: 1. 字符串字面量(如示例1)存储在程序的只读数据段,尝试修改(如`str1[0]='h';`)会导致段错误(引用[3])。 2. 字符数组(如示例2)在栈上分配,可以修改。 3. 动态分配(如示例3)在堆上分配,需要手动管理内存(使用free释放)。 另外,引用[4]提到,char类型实际存储的是整数(ASCII),因此也可以用%c逐个输出字符,但字符串通常用%s整体输出。 §§相关问题§§ 1. 如何安全地输入字符串以避免缓冲区溢出? 2. 字符串字面量和字符数组在内存中的存储位置有何不同? 3. 如何输出字符串中的单个字符? 4. 如何处理中文字符串的输出(引用[3]提到乱码问题)? 5. 如何连接两个字符串并输出?</think>### C语言中输出字符串(char*)的完整指南 在C语言中输出字符串主要通过`printf()`函数配合`%s`格式符实现。以下是详细说明和示例代: #### 一、基础输出方法 ```c #include <stdio.h> int main() { // 方法1:直接输出字符串字面量 printf("直接输出: %s\n", "Hello World"); // 输出: Hello World // 方法2:通过char指针输出 char *str1 = "C Language"; printf("指针输出: %s\n", str1); // 输出: C Language // 方法3:输出字符数组 char str2[] = "Character Array"; printf("数组输出: %s\n", str2); // 输出: Character Array return 0; } ``` #### 二、关键特性说明 1. **`%s`格式符**: - 自动输出直到`\0`(空字符)结束 - 不会自动换行(需手动加`\n`)[^1] 2. **字符串存储方式对比**: | 类型 | 示例 | 可修改性 | 内存位置 | |------|------|----------|----------| | `char*` | `char *s = "text";` | 只读(常量区) | 代段 | | `char[]` | `char s[] = "text";` | 可修改 | 栈/堆 | 3. **输出带格式控制**: ```c char *url = "https://example.com"; printf("格式化输出: %.*s\n", 8, url); // 输出: https:// ``` #### 三、中文输出与编问题 ```c #include <stdio.h> #include <locale.h> int main() { setlocale(LC_ALL, ""); // 设置本地化支持中文 char *chinese = "你好世界"; printf("中文输出: %s\n", chinese); // 需确保源文件使用UTF-8编[^3] return 0; } ``` **常见乱码解决方案**: 1. 源文件保存为UTF-8编 2. 终端使用UTF-8编模式 3. 使用`setlocale(LC_ALL, "")`初始化本地化 #### 四、动态字符串输出 ```c #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { // 动态分配字符串 char *dynamic_str = (char*)malloc(20 * sizeof(char)); strcpy(dynamic_str, "Dynamic String"); printf("动态字符串: %s\n", dynamic_str); // 输出: Dynamic String free(dynamic_str); // 必须释放内存 return 0; } ``` #### 五、安全输出注意事项 1. **防溢出**:指定最大输出长度 ```c char long_str[100] = "This is a very long string..."; printf("%.10s...\n", long_str); // 输出: This is a ... ``` 2. **空指针检查**: ```c char *possible_null = NULL; if(possible_null) { printf("%s\n", possible_null); } else { printf("(null)\n"); // 避免段错误 } ``` #### 六、特殊场景处理 1. **输出指针数组中的字符串**: ```c char *languages[] = {"C", "C++", "Python", NULL}; for(int i=0; languages[i]; i++) { printf("%d: %s\n", i+1, languages[i]); // 输出多个字符串 } ``` 2. **逐字符输出**: ```c char *text = "ASCII"; for(char *p = text; *p; p++) { printf("%c(%d) ", *p, *p); // 输出: A(65) S(83) C(67) I(73) I(73) } ``` > **最佳实践**:优先使用`char[]`存储需修改的字符串,`char*`仅用于指向常量字符串[^2][^3]。 --- **相关问题** 1. 如何安全地输入字符串到`char*`指针? 2. `char* str`和`char str[]`在函数参数传递中有何区别? 3. 多字节字符(如中文)在字符串操作中需要注意什么? 4. 如何实现带格式的字符串拼接后再输出? 5. 字符串输出性能优化有哪些常用技巧?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值