C++: string<-->char
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的更多相关文章
- C++中int,float,string,char*的转换(待续)
//float转string char a[100]; float b = 1.234; sprintf(a, "%f", b); string result(a); //int转 ...
- C#入门篇6-6:字符串操作 StringBiulder string char[]之间的转化
//StringBiulder string char[]之间的转化 public static void Fun3() { StringBuilder sb = new StringBuilder( ...
- CString string char* char 之间的字符转换(多种方法)
在写程序的时候,我们经常遇到各种各样的类型转换,比如 char* CString string 之间的互相转换.首先解释下三者的含义. CString 是一种很有用的数据类型.它们很大程度上简化了MF ...
- C++ wstring string char* wchar_t相互转换
标签: stringwstringwchar_tcharc++2013-12-19 00:29 3721人阅读 评论(0) 收藏 举报本文章已收录于: C++知识库 分类: C/C++(50) 1. ...
- string,char*,int 之间的转化
c++中经常遇到string,char*,int之间的相互转化,今天就来整理一下. 以下是转载并修改的内容: 以下是常用的几种类型互相之间的转换 string 转 int先转换为char*,再使用at ...
- 【转】CString,string,char*综合比较
(一) 概述 1.string和CString均是字符串模a板类: 2.string为标准模板类(STL)定义的字符串类,已经纳入C++标准之中: 3.CString(typedef CString ...
- mfc CString,string,char* 之间的转换
知识点: CString转char*,string string转char*,CString char* 转CString,string 一.CString转char*,string //字串转换测试 ...
- (c++) int 转 string,char*,const char*和string的相互转换
一.int 和string的相互转换 1 int 转化为 string c++ //char *itoa( int value, char *string,int radix); // 原型说明: / ...
- (C/C++) string / *char / int 基本轉換
網路上有許 string / *char / integer 基本轉換方式 string 與 *char 互相轉換的方法 /* string to *char */ string ssbuf1 = & ...
- string char * const char *之间的互相转换
string -> const char * 用str的c_str()方法或者data()方法均可,这个两个方法返回值为cong char * string str = "hel ...
随机推荐
- nfs下的exportfs命令和nfs客户端重新挂载
工作中,如果使用了nfs服务器,会遇到修改nfs服务器配置的情况,如果想重新让客户端加载上修改后的配置,但是又不能重启rpcbind服务,我们需要使用export命令了 exportfs命令 常用选项 ...
- 为什么Netty这么火?与Mina相比有什么优势?
Netty是什么?为什么这么火? Netty是目前最流行的由JBOSS提供的一个Java开源框架NIO框架,Netty提供异步的.事件驱动的网络应用程序框架和工具,用以快速开发高性能.高可靠性的网络服 ...
- vue中beforeRouteEnter 执行的时机及运用的误区?
beforeRouteEnter钩子 beforeRouteEnter (to, from, next) { console.log(this); //undefined,不能用this来获取vue实 ...
- usb-host与外设之间的通信(一)
迫于需要开始一个app实现安卓手机控制外设,要学习一下usb-host这方面的知识,所以记录一下自己的学习经历.关于usb-host这一块的资料国内还是比较少的,我只能学到哪里就记录到哪里了. 简单来 ...
- 字节流read方法返回值为什么是int不是byte
01001000 01001000 01001000 11111111 01001000 -1的原码: 10000001 -1的反码: 11111110 -1的补码: 11111111 所以如果返回值 ...
- Dubbo支持的注册中心有哪些?
1.Dubbo协议(官方推荐协议) 优点: 采用NIO复用单一长连接,并使用线程池并发处理请求,减少握手和加大并发效率,性能较好(推荐使用) 缺点: 大文件上传时,可能出现问题(不使用Dubbo文件上 ...
- python_django_template_url反向解析
什么是url反向解析? 一般我们网址在diango内部匹配顺序为:网址→ url → views → templates → <a href="suck/good/"> ...
- nodejs route的简单使用
demo var express=require('express'); var app=express(); var routeUser=express.Router(); var routeTea ...
- 51 eigen、boost等基础库学习
0 引言 eigen库是一个高层次的C++库,有效支持线性代数,矩阵和矢量运算,数值分析及其相关的算法.eigen除了C++标准库之外,不需要任何其他的依赖包.Eigen使用的CMake建立配置文件和 ...
- 47 ubuntu指令整理学习
0 引言 在使用ubutnu时,积累了大量命令笔记.但是这些笔记比较零散,没有系统性,不便于查找和使用.通过系统性.分门别类地整理,希望可以增强对指令的记忆,提高工作效率,对ubuntu的使用更加地道 ...