C++_如何得到类内字符串内容

来源:互联网 发布:黑暗之魂 隐藏 知乎 编辑:程序博客网 时间:2024/05/21 09:01

在项目中遇到一个问题,在类外希望得到类中的字符串内容。

通过直接传递字符串指针实际并不能修改内容

可行的方法:

1.传递字符串数组的地址

2.传递字符串二级指针,即字符串地址

3.按照C++的方式传递一个 string引用, 通过引用直接修改



失败的方式:(截取代码:将函数封装到类里了,....代码太多,总体测试代码在文章末尾.感兴趣的同学自己复制)

void GetStringC(char *a){a = "Hi,Kemeng~: GetStringC";}

char * a2 = NULL;test.GetStringC(a2);printf("\n%s\n", a2);


可以看到实际上a2的值并没有发生改变这是为什么呢??


所以原因如下:形参a  在函数结束的时候已经被释放了,而本身只是改变了a  的值 ,让其指向 "Hello, KeMeng~"字符串,并没有更改a2,所以输出仍为null,那我们想到了以下办法:


实际上 参数的传递都是存在一次赋值的:

实参给形参赋值好比以下代码:

printf("\nTest of Assign of Char pointer\n""Print their address\n");char * p2 = "Hello, KeMeng~";char * p3 = p2;printf("p2:%p    p3:%p\n", p2, p3);

p2好比上面的实参a2,     p3相当于形参a.

输出:


这么样一次复制相当于将p2与p3都指向了一块地址, 这个地址存放着 常量字符串    "Hello, KeMeng~"


但是p2. p3指针的地址是不一样的

printf("\nTest of Assign of Char pointer\n""Print their address\n");char * p2 = "Hello, KeMeng~";char * p3 = p2;printf("p2:%p    p3:%p\n", p2, p3);printf("address of p2:%p, address of p3:%p\n", &p2, &p3);


这里不得不说一下:

char *p = "Hi, Kemeng";

这里的字符串"Hi, Kemeng"是不可修改的


原因见如下:

2."abc"是常量吗?答案是有时是,有时不是。

  不是常量的情况:"abc"作为字符数组初始值的时候就不是,如
                  char str[] = "abc";
    因为定义的是一个字符数组,所以就相当于定义了一些空间来存放"abc",而又因为
    字符数组就是把字符一个一个地存放的,所以编译器把这个语句解析为
    char str[3] = {'a','b','c'};
                  又根据上面的总结1,所以char str[] = "abc";的最终结果是
    char str[4] = {'a','b','c','\0'};
    做一下扩展,如果char str[] = "abc";是在函数内部写的话,那么这里
    的"abc\0"因为不是常量,所以应该被放在栈上。
  
  是常量的情况:  把"abc"赋给一个字符指针变量时,如
                  char* ptr = "abc";
    因为定义的是一个普通字符指针,并没有定义空间来存放"abc",所以编译器得帮我们
    找地方来放"abc",显然,把这里的"abc"当成常量并把它放到程序的常量区是编译器
    最合适的选择。

相关文章链接:

http://blog.csdn.net/u010003835/article/details/48087629


所以以下方式是不可行的:

void ChangeStringA(char *a){a[0] = 'H';a[1] = 'i';a[2] = ':';a[3] = '\0';}

printf("\ntest.ChangeStringA(hh):\n");char *hh = "Hello, KeMeng~";printf("%s\n", hh);test.ChangeStringA(hh);//errorprintf("%s\n", hh);





但是指针p 所指的空间可以修改(指向其他位置)

printf("\nTest of change char pointer content\n");char * p4 = "Hello, KeMeng~";printf("p4: %s\n", p4);p4 = "Hi";printf("p4: %s\n", p4);




下面介绍几种可行的方式:


1.传递字符串数组的地址(两种写法)

<pre name="code" class="cpp">void ChangeStringB(char *a){strcpy(a, "Hi:");}void ChangeStringC(char a[]){strcpy(a, "Hi:");}

printf("\ntest.ChangeStringB(dd):\n");char dd[100] = "Hello, KeMeng~";printf("%s\n", dd);test.ChangeStringB(dd);printf("%s\n", dd);printf("\ntest.ChangeStringC(ff):\n");char ff[100] = "Hello, KeMeng~";printf("%s\n", ff);test.ChangeStringC(ff);printf("%s\n", ff);


2.传递字符二级指针,即字符指针的地址(方法丑陋不建议使用)

void GetStringB(char **a){*a = "Hi,Kemeng~: GetStringB";}

char * aa = NULL;test.GetStringB(&aa);printf("\n%s\n", aa);






3.按照C++的方式传递一个 string引用, 通过引用直接修改

void GetStringA(string &a){a = "Hi,Kemeng~: GetStringA";}
string cstring;test.GetStringA(cstring);printf("\n%s\n", cstring.c_str());





另附上完整测试代码供大家参考:

#include <iostream>#include <string>using namespace std;#pragma warning(disable:4996)class A{public:void GetStringA(string &a){a = "Hi,Kemeng~: GetStringA";}void GetStringB(char **a){*a = "Hi,Kemeng~: GetStringB";}void GetStringD(char *a){strcpy(a, "Hi,Kemeng~: GetStringD");}void GetStringE(char a[]){strcpy(a, "Hi,Kemeng~: GetStringE");}void GetStringC(char *a){a = "Hi,Kemeng~: GetStringC";}void PrintStringAddress(char *a){printf("%p\n", a);}void PrintCharPointAddress(char *a){printf("%p\n", &a);}void ChangeStringA(char *a){a[0] = 'H';a[1] = 'i';a[2] = ':';a[3] = '\0';}void ChangeStringB(char *a){strcpy(a, "Hi:");}void ChangeStringC(char a[]){strcpy(a, "Hi:");}};int main(){A test;string cstring;test.GetStringA(cstring);printf("\n%s\n", cstring.c_str());//char * aa = NULL;//test.GetStringB(&aa);//printf("\n%s\n", aa);//char * a2 = NULL;//test.GetStringC(a2);//printf("\n%s\n", a2);//printf("\ntest.PrintStringAddress(bb):\n");//char *bb = "Hello, KeMeng~";//printf("%p\n", bb);//test.PrintStringAddress(bb);//printf("\ntest.PrintCharPointAddress(c2):\n");//char *c2 = "Hello, KeMeng~";//printf("%p\n", &c2);//test.PrintCharPointAddress(c2);//printf("\nTest of Assign of Char pointer\n"//"Print their address\n");//char * p2 = "Hello, KeMeng~";//char * p3 = p2;//printf("p2:%p    p3:%p\n", p2, p3);//printf("address of p2:%p, address of p3:%p\n", &p2, &p3);//注意 "Hello, KeMeng~" 存放在字符串内存空间中//p2[1] = '\0';//printf("%s\n", p2);//printf("\nTest of change char pointer content\n");//char * p4 = "Hello, KeMeng~";//printf("p4: %s\n", p4);//p4 = "Hi";//printf("p4: %s\n", p4);////printf("\ntest.ChangeStringC(cc):\n");//char *cc = "Hello, KeMeng~";//printf("%s\n", cc);//test.ChangeStringC(cc);//error//printf("%s\n", cc);//printf("\ntest.ChangeStringC(c3):\n");//char *c3 = "Hello, KeMeng~";//printf("%s\n", &c3);//test.ChangeStringC(c3);//error//printf("%s\n", c3);//printf("\ntest.ChangeStringB(dd):\n");//char dd[100] = "Hello, KeMeng~";//printf("%s\n", dd);//test.ChangeStringB(dd);//printf("%s\n", dd);//printf("\ntest.ChangeStringC(ff):\n");//char ff[100] = "Hello, KeMeng~";//printf("%s\n", ff);//test.ChangeStringC(ff);//printf("%s\n", ff);//printf("\ntest.ChangeStringC(gg):\n");//char gg[100] = "Hello, KeMeng~";//printf("%s\n", gg);//test.ChangeStringA(gg);//printf("%s\n", gg);//printf("\ntest.ChangeStringA(hh):\n");//char *hh = "Hello, KeMeng~";//printf("%s\n", hh);//test.ChangeStringA(hh);//error//printf("%s\n", hh);return 0;}



1 0
原创粉丝点击