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. vs设置html的模板快

    打开vs编辑器,点击文件-->首选项-->用户代码片段 之后选择先对应的编辑器模板 进入里面编写相对应的代码块 之后直接在编辑器中调用.

  2. angularJS 上传multipart/form-data

    var fd = new FormData();fd.append('file', vm.file);CommodityViewImport.post(fd, onSaveSuccess, onSav ...

  3. &与&&,|与||的区别

    今天在做leetcode的时候,遇到了运算符的不同而导致结果不一致的问题.记录一下提醒自己 中文名称与英文名称 &:按位与(Bitwise and) &&:逻辑与(logica ...

  4. MySQL 小调研

    一. 概况: MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品.MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL ...

  5. ADS 命令行命令介绍

    armasm 1. 命令:armasm [选项] -o 目标文件 源文件 2. 选项说明 -Errors 错误文件名        ;指定一个错误输出文件 -I 目录[,目录]          ;指 ...

  6. vt-is-UTF8 - check whether current VT is in UTF8- or byte-mode. 检查当前VT是否处于VTF8模式或是字节模式.

    总览 vt-is-UTF8 [-h|--help] [-V|--version] [-q|--quiet] 描述 vt-is-UTF8 checks whether the current VT is ...

  7. mount 挂载

    mount 挂载出现 这是咋回事.找了找度娘,说是磁盘没有格式化.好吧,mkfs ext4 /dev/sda4 ,提示 没有有效的快给格式化,好奇怪啊,昨天明明分号区了,我记错了. fdisk看一下, ...

  8. zmq利用protobuf通信

    protobuf序列化之后为二进制数据,数据中可能包含 ‘\0’,直接转换为char *类型会导致发送数据不完整.解决方法: void buildProtobufMsg(const string&am ...

  9. vue之axios的使用

    一.环境安装 1.axios的安装 进入到对应工程目录执行: npm install axios 2.启动测试数据的API 测试项目地址:https://github.com/ShenJianPing ...

  10. 修改Ubuntu16.04默认主题标题栏的颜色

    默认主题为Ambiance: sudo gedit /usr/share/themes/Ambiance/gtk-3.0/gtk-main.css 将: @define-color dark_bg_c ...