1. char*、char[] 与 std::string 之间的区别:

char*是一个指向字符的指针,是一个内置类型。可以指向一个字符,也可以表示字符数组的首地址(首字符的地址)。我们更多的时候是用的它的第二的功能,来表示一个字符串,功能与字符串数组char ch[n]一样,表示字符串时,最后有一个 '\0'结束符作为字符串的结束标志。

#include <iostream>

int main()
{
char ch1 = 'c';
char ch2[] = "Hello Wrold"; char* pch1 = "string";
char* pch2 = ch2;
char* pch3 = &ch1;
char* pch4 = &ch2[]; std::cout << ch2 << std::endl; // 输出ch2[0]到\0之前的所有字符
std::cout << pch1 << std::endl; // 输出ch1[0]到\0之前的所有字符
std::cout << pch2 << std::endl; // 输出ch2[0]到\0之前的所有字符
std::cout << pch4 << std::endl; // 输出ch2[2]到\0之前的所有字符
std::cout << *pch3 << std::endl; // 解引用pch3,输出pch3指向的字符
std::cout << *pch4 << std::endl; // 解引用pch4,输出pch4指向的字符 return ;
}

输出:

Hello Wrold
string
Hello Wrold
llo Wrold
c
l

char p[], 表示 p 是一个字符串的数组;
    std::string s, 表示 s 是一个 std::string 类的对象。

#include <iostream>

int main()
{
char p1[] = "";
char* p2 = "";
std::string p3 = "";
std::cout << "sizeof(p1) is: " << sizeof(p1) << std::endl;
std::cout << "strlen(p1) is: " << strlen(p1) << std::endl;
std::cout << "sizeof(p2) is: " << sizeof(p2) << std::endl;
std::cout << "strlen(p2) is: " << strlen(p2) << std::endl;
std::cout << "sizeof(p3) is: " << sizeof(p3) << std::endl;
std::cout << "strlen(p3) is: " << strlen(p3.c_str()) << std::endl;
std::cout << "length(p3) is: " << p3.length() << std::endl;
std::cout << "capacity(p3) is: " << p3.capacity() << std::endl; return ;
}

输出结果如下:

sizeof(p1) is:
strlen(p1) is:
sizeof(p2) is:
strlen(p2) is:
sizeof(p3) is:
strlen(p3) is:
length(p3) is:
capacity(p3) is:

p1是 char 型数组名称,sizeof(p1)表示数组的长度(整个数组所占的字节数);
    p2是指向 char 类型的指针,sizeof(p2)表示其所指向的地址值所占的字节数;
    p3是 std::string 类型的对象,sizeof(p3)是 std::string 类型所占空间的大小,无论赋给它多长的字符串,sizeof(p3)都是固定值28;
    strlen函数统计字符串的长度,但不包含结束符’\0’,std::string 类的 length 函数同样是统计字符串长度,std::string 类的 capacity 函数的返回值一定会大于等于字符串的长度,std::string 会预先分配一定的空间,空间不足时会重新分配。

2. char*、char[] 与 std::string 之间的转换

首先必须了解,string可以被看成是以字符为元素的一种容器。字符构成序列(字符串)。有时候在字符序列中进行遍历,标准的string类提供了STL容器接口。具有一些成员函数比如begin()、end(),迭代器可以根据他们进行定位。

注意,与char*不同的是,string不一定以NULL('\0')结束。string长度可以根据length()得到,string可以根据下标访问。所以,不能将string直接赋值给char*。

(1)string 转换成 char*

如果要将string直接转换成const char *类型,可以直接赋值,string有2个函数可以运用。一个是.c_str(),一个是data成员函数。

#include <iostream>
#include <string> int main()
{
std::string str = "abcdeg";
const char* k = str.c_str();
const char* t = str.data(); printf("%s%s\n", k, t);
std::cout << k << t << std::endl; return ;
}

如上,都可以输出。内容是一样的。但是只能转换成const char*,如果去掉const编译不能通过。

那么,如果要转换成char*,可以用string的一个成员函数copy实现。

#include <iostream>
#include <string> int main()
{
std::string str = "abcdefg"; int len = str.length();
char* data = (char *)malloc((len + ) * sizeof(char));
str.copy(data, len, ); printf("%s\n", data);
std::cout << data << std::endl; return ;
}

(2)string 转换成 char[]

不可以直接赋值。可以循环char*字符串逐个字符赋值,也可以使用strcpy_s等函数(需调用string对象的c_str函数,返回类型为const char* )。

这样的转换不可直接赋值。

#include <iostream>
#include <string> int main()
{
std::string str = "dagah";
char ch[]; int i = ;
for( ; i < str.length(); ++i)
{
ch[i] = str[i];
}
ch[i] = '\0'; printf("%s\n", ch);
std::cout << ch << std::endl; return ;
}

(3)char* 转换成 string

可以直接赋值。

#include <iostream>
#include <string> int main()
{
char* ch = "adghrtyh";
std::string str = ch;

printf("%s\n", str.c_str());
std::cout << str << std::endl; return ;
}

不过这个是会出现问题的。

有一种情况我要说明一下。当我们定义了一个string类型之后,用printf("%s", str);输出是会出问题的。这是因为“%s”要求后面的对象的首地址。但是string不是这样的一个类型。所以肯定出错。

(4)char[] 转换成 string

这个也可以直接赋值。但是也会出现上面的问题。需要同样的处理。

(5)char* 转换成 char []

不能直接赋值,可以循环 char* 字符串逐个字符赋值,也可以使用strcpy_s等函数。

char *p="ertyu";

char r[10];

strcpy(r,p);

(6)char[] 转换成 char*

可以直接赋值。

问题:

1、char* pch = "abc"; // caution:ISO C++11 doesn't allow conversion from string literal to 'char*'

系统为可执行文件写下常量字符串,保存在可执行文件里,运行的时候加载到内存中,无法修改。
    解决办法:
    A、标准方法:将指针转换为char const *类型
    char const* pch = "abc";
    B、将字符串强制转换为char*类型
    char* pch = (char*)"abc";

2、char *pch = 'a';
    char *pch = &'a';
    第一行由于'a'是一个char类型的字符,并不是一个有效的地址,无法用来初始化char*
    第二行由于无法直接取到'a'这个char类型字符的地址。

解决办法:
    A、动态内存申请:
    char* pch = new char('a');

B、初始化一个新变量:
    char ch = 'a';
    char* pch = &ch;

注意:char *pch=ch是错误的,因为ch是一个char型变量的变量名,并不是一个有效地址。

3、Q: What is the difference between these initializations?
    char a[] = "string literal";
    char *p = "string literal";
    My program crashes if I try to assign a new value to p[i].

A: A string literal (the formal term for a double-quoted string in C source) can be used in two slightly different ways:

As the initializer for an array of char, as in the declaration of char a[] , it specifies the initial values of the characters in that array (and, if necessary, its size).
    Anywhere else, it turns into an unnamed, static array of characters, and this unnamed array may be stored in read-only memory, and which therefore cannot necessarily be modified. In an expression context, the array is converted at once to a pointer, as usual (see section 6), so the second declaration initializes p to point to the unnamed array's first element.
    Some compilers have a switch controlling whether string literals are writable or not (for compiling old code), and some may have options to cause string literals to be formally treated as arrays of const char (for better error catching).

C and C++ differ in the type of the string literal. In C the type is array of char and in C++ it is constant array of char. In any case, you are not allowed to change the characters of the string literal, so the const in C++ is not really a restriction but more of a type safety thing. A conversion from const char* to char* is generally not possible without an explicit cast for safety reasons. But for backwards compatibility with C the language C++ still allows assigning a string literal to a char* and gives you a warning about this conversion being deprecated.

4、int/double 与 char*/std::string的转换

     //-------------------------------------------------
// double/int --> char*
// itoa 不是标准库函数 // int-->char*
int digit1 = ;
char str1[];
sprintf(str1, "%d", digit1); // double-->char*
double digit2 = 168.2;
char str2[];
sprintf(str2, "%f", digit2); // link
char* str3 = "Hello";
char* str4 = "World"; //
char str5[];
strcpy(str5, str3);
strcat(str5, str4); //
char str6[];
sprintf(str6, "%s%s", str1, str2); // 两个double转为char*
double digit7 = 12.3;
double digit8 = 23.4;
char str7[];
sprintf(str7, "%f%f", digit7, digit8);
//------------------------------------------------- //-------------------------------------------------
// char*-->double/int
// atoi atof
// ... double digit9 = atof(""); //------------------------------------------------- //-------------------------------------------------
// double/int --> std::string
// std::to_string()
double digit11 = 451.7;
std::string str11 = "score" + std::to_string(digit11);
//------------------------------------------------- //-------------------------------------------------
// std::string-->double/int
// std::stoi std::stof std::stol
std::string str12("");
double digit12 = std::stof(str12);
//-------------------------------------------------

参考:

https://stackoverflow.com/questions/28861475/conversion-from-string-literal-to-char
https://stackoverflow.com/questions/1704407/what-is-the-difference-between-char-s-and-char-s/1704433#1704433
https://stackoverflow.com/questions/164194/why-do-i-get-a-segmentation-fault-when-writing-to-a-string-initialized-with-cha
https://stackoverflow.com/questions/9650058/deprecated-conversion-from-string-literal-to-char
https://stackoverflow.com/questions/1524356/c-deprecated-conversion-from-string-constant-to-char

http://c-faq.com/decl/strlitinit.html
https://www.codeguru.com/cpp/cpp/cpp_mfc/general/article.php/c6967/Constant-Pointers-and-Pointers-to-Constants.htm
https://blog.csdn.net/doem97/article/details/51730225

C++: string<-->char的更多相关文章

  1. C++中int,float,string,char*的转换(待续)

    //float转string char a[100]; float b = 1.234; sprintf(a, "%f", b); string result(a); //int转 ...

  2. C#入门篇6-6:字符串操作 StringBiulder string char[]之间的转化

    //StringBiulder string char[]之间的转化 public static void Fun3() { StringBuilder sb = new StringBuilder( ...

  3. CString string char* char 之间的字符转换(多种方法)

    在写程序的时候,我们经常遇到各种各样的类型转换,比如 char* CString string 之间的互相转换.首先解释下三者的含义. CString 是一种很有用的数据类型.它们很大程度上简化了MF ...

  4. C++ wstring string char* wchar_t相互转换

    标签: stringwstringwchar_tcharc++2013-12-19 00:29 3721人阅读 评论(0) 收藏 举报本文章已收录于: C++知识库 分类: C/C++(50) 1. ...

  5. string,char*,int 之间的转化

    c++中经常遇到string,char*,int之间的相互转化,今天就来整理一下. 以下是转载并修改的内容: 以下是常用的几种类型互相之间的转换 string 转 int先转换为char*,再使用at ...

  6. 【转】CString,string,char*综合比较

    (一)  概述 1.string和CString均是字符串模a板类: 2.string为标准模板类(STL)定义的字符串类,已经纳入C++标准之中: 3.CString(typedef CString ...

  7. mfc CString,string,char* 之间的转换

    知识点: CString转char*,string string转char*,CString char* 转CString,string 一.CString转char*,string //字串转换测试 ...

  8. (c++) int 转 string,char*,const char*和string的相互转换

    一.int 和string的相互转换 1 int 转化为 string c++ //char *itoa( int value, char *string,int radix); // 原型说明: / ...

  9. (C/C++) string / *char / int 基本轉換

    網路上有許 string / *char / integer 基本轉換方式 string 與 *char 互相轉換的方法 /* string to *char */ string ssbuf1 = & ...

  10. string char * const char *之间的互相转换

    string  ->   const char * 用str的c_str()方法或者data()方法均可,这个两个方法返回值为cong char * string str = "hel ...

随机推荐

  1. 天道神诀--IPSAN(iscsi配置)

    数据存储技术 DSA(Direct Attacted Storage 直接附加存储)本地硬盘 NAS(Network Attacted Storage 网络附加存储)网络服务共享:文件夹 SAN(St ...

  2. 如果手工启动chromedriver

    使用selenium模拟登陆网站时,有些网站会识别chrome driver里的json信息,从而判断是不是爬虫程序,做到反爬效果.(比如知乎) 下面说明下怎么手动启动chromedriver 1). ...

  3. HTTP信息头处理器

    就是HTTP请求头-Header

  4. Windows跳板机无法共享本地主机剪贴板

    我的跳板机是Windows 2003 ,总是无法共享本地的剪贴板,我一般是在本地编辑SQL或者一些脚本,然后粘贴到跳板机中. 如果碰到无法共享本地剪贴板的情况,可以尝试按照以下步骤解决: 开始 -- ...

  5. react 父子组件传值

    父组件向子组件传递信息 父组件片段 constructor(props){ super(props) this.state={ message:"我是父组件传来的" } } ren ...

  6. nginx防DDOS、cc、爬虫攻击

    一.防止DDOS.CC攻击 http { limit_conn_zone $binary_remote_addr zone=perip:10m; limit_conn_zone $server_nam ...

  7. Qt 【无法打开 xxxx头文件】

    经过多次磕碰,终于发现了通用的办法. 测试环境Qt5.5.1 mvcs 比如需要用到QtWin 直接去包含然后运行,but fail, 我去查找他的父类  QtWinExtras Qt自带的自动补全, ...

  8. JAVA call dll

    { System.loadLibrary():装载Windows\System32下或jre\bin或Tomcat\bin目录下的本地链接库 System.load():根据具体的目录来加截本地链接库 ...

  9. 【NOI2019模拟2019.6.27】B (生成函数+整数划分dp|多项式exp)

    Description: \(1<=n,k<=1e5,mod~1e9+7\) 题解: 考虑最经典的排列dp,每次插入第\(i\)大的数,那么可以增加的逆序对个数是\(0-i-1\). 不难 ...

  10. NX二次开发-UFUN创建球UF_MODL_create_sphere1

    NX11+VS2013 #include <uf.h> #include <uf_modl.h> UF_initialize(); //创建球 UF_FEATURE_SIGN ...