c++中char[]与char*的转换以及char*与数字互转

    在c/c++中,字符串操作不可避免,而且通常,char*或者char[]就能表示字符串,这个跟java语言有很大的差别,java中char是字符,string才是字符串,他们是完全不一样的概念。在c/c++中,虽然string也可以表示字符串,但是char*表示字符串还是更常见。

    既然char*和char[]都可以表示字符串,他们之间的转换是如何的呢?另外,如果字符串中都是数字,如何将他们转换为整数或者浮点数,反过来,数字如何转字符串,这个在日常的编程中,都是必须要掌握的技巧。

    先来总结一下char*与char[]的互转:

    一般来说,字符串的表示可以是char*,也可以是char[],这里呢,char*字符指针,表示的虽然是一个指针,但是也是一个字符串,它表示一个以'\0'结束的字符串。char[]表示的虽是一个字符数组,但同样也是一个字符串。

    他们都可以直接赋值:

    char* str = "hello";   这种表示方法是有问题的,如果在vs编辑器中,它会提示"hello"是一个常量,不可修改,需要const修饰符修饰,所以最终它只能表示为const char* str="hello";

     

    char str1[] = "hello";   这种表示法,编译器会认为它也是一个常量,并且给出了长度char str1[6]。这种表示方式,编译器不会强制我们在前面加上const修饰符。

    

    另外,char[]这种表示方法,我们可以直接在声明的时候,就给出长度,比如:

char str[6] = "12345";

    因为字符数组的最后一位需要用'\0'来填充,表示结束符,所以他的长度总是要在字符实际长度的基础上+1,这是一个永恒不变的定律。所以,在字符串拷贝的时候,我们经常见到这样的初始化表达式:  

char* str1 = new char[strlen(str)+1];

    而上面的char str[6] = "12345";字符串表示,之所以长度初始化为6,也就是这个原因了。这个长度,只能设置大,最少设置为刚刚好,多数情况下,我们会设置一个偏大的值,比如20、100等,如果我们不想设置,可以留空,让编译器自己来默认设置,就是如下的表示方式了:

char str[] = "hello,world.";

    这样,编译器会默认将数组长度设置为13。 

    那么问题来了,如果我们不注意,把长度设置小了怎么办? 编译阶段就会报错。

    

    1、  char[]  -> char*    :通过"="直接赋值

char str1[] = "hello";
char* str2 = str1;
cout<<"str1="<<str1<<"\nstr2="<<str2<<endl; 

     2.1、char* -> char*   :借助strcpy()拷贝赋值

const char* str3 = "1234";
char* str4 = new char[strlen(str3)+1];
strcpy(str4,str3);
cout<<"str3="<<str3<<"\nstr4="<<str4<<endl;

    2.2、char* -> char[]     :借助strcpy()拷贝赋值 

const char* str5 = "helloworld";
char str6[11];
strcpy(str6,str5);
cout<<"str5="<<str5<<"\nstr6="<<str6<<endl;

    通过上面的示例,我们知道,如果是char[]->char*,就是直接赋值,如果是char*->char?,就是拷贝赋值,因为无论是char*还是char[],他们都需要先指定一个数组长度进行初始化,然后进行挨个下标拷贝,也就是拷贝赋值。

    其实,都是字符串,为什么这么多讲究,还有这么多区别,我也理解的不是很深入,但是通过这些例子,我自己是明白了。

    接下来,我们来看看字符串转数字的办法:

    1、sscanf()  

//sscanf
char str7[] = "3.1415";
double num7;
sscanf(str7,"%lf",&num7);
cout<<"num7="<<num7<<endl; // 3.1415

    2、strtod()

char str9[] = "24.876543E+001";
double num9;
num9 = strtod(str9,NULL);
cout<<"num9="<<num9<<endl; // 248.765

    3、atof()

//atof
char str8[] = "15.6";
double num8;
num8 = atof(str8);
cout<<"num8="<<num8<<endl; // 15.6

    如果字符串表示的是整数(int类型),还可以通过atoi()方法。

    反过来,数字转字符串:

    1、整数可以通过itoa(),c++中需要改为_itoa()

int i = 999;
char c[4];
_itoa(i,c,10);
cout << "c=" << c << endl;

    再次可以看出,char[]数组长度需要指定一个合适的长度。

    2、sprintf(),格式化,和sscanf()类似,这里是将数字转为字符串。

double num10 = 12.3;
char str10[5];
sprintf(str10,"%.1lf",num10);
cout << "str10=" << str10 << endl;

    这里如果是浮点数转换为字符串,有个问题,就是浮点数的小数点位数和格式化的参数有很大关系,这里不能一概而论,就是sprintf(str10,"%.1lf",num10),其中"%.1lf"是格式化后一位小数,如果是"%.2lf"就是两位小数,以此类推。所以这个格式化不是一个标准的办法。

   3、借助sstream的stringstream字符流工具。

double value;
stringstream ss;
string str;
value = 3.1415;
ss << value;
ss >> str;
cout << "str=" << str << endl;

     个人感觉,c/c++对字符串的操作显然很谨慎,有很多讲究,而在java中,这种操作几乎是无缝对接的。只要他们本身没有大问题,转换都封装好了,Integer.parseInt(str),new String(value)。而在javascript中,这种转换就更加的直接,parseInt(),parseFloat(),数字转字符串就更加简单了,他们直接在数字前面拼接一个""就可以了,比如""+123。

    以上完整代码如下所示:

#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
#define _CRT_SECURE_NO_DEPRECATE
#endif
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main() {
    //=
    char str1[] = "hello";
    char* str2 = str1;
    cout << "str1=" << str1 << "\nstr2=" << str2 << endl;
    //strcpy
    const char* str3 = "1234";
    char* str4 = new char[strlen(str3) + 1];
    strcpy(str4, str3);
    cout << "str3=" << str3 << "\nstr4=" << str4 << endl;
    //strcpy
    const char* str5 = "helloworld";
    char str6[11];
    strcpy(str6, str5);
    cout << "str5=" << str5 << "\nstr6=" << str6 << endl;
    //sscanf
    char str7[] = "3.1415";
    double num7;
    sscanf(str7, "%lf", &num7);
    cout << "num7=" << num7 << endl;
    //atof
    char str8[] = "15.6";
    double num8;
    num8 = atof(str8);
    cout << "num8=" << num8 << endl;
    //strtod
    char str9[] = "24.876543E+001";
    double num9;
    num9 = strtod(str9, NULL);
    cout << "num9=" << num9 << endl;
    //sprintf
    double num10 = 12.3;
    char str10[5];
    sprintf(str10,"%.1lf",num10);
    cout << "str10=" << str10 << endl;
    //ecvt
    /*
    char* str11;
    int dec, sign;
    int dig = 10;
    double num11 = 9.86;
    str11 = _ecvt(num11, dig, &dec, &sign);
    cout << "str11=" << str11 << endl;
    */
    double value;
    stringstream ss;
    string str;
    value = 3.1415;
    ss << value;
    ss >> str;
    cout << "str=" << str << endl;
    return 0;
}

    运行,打印结果如下:

     

    我们可以确定的是,char如果表示字符串是一个以'\0'结束的字符串,长度是真实长度+1。 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luffy5459

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值