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

2023-05-16

    在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。 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐

  • tmux基本操作

    tmux是什么 tmux xff08 terminal multiplexer xff09 是Linux上的终端复用神器 xff0c 可从一个屏幕上管理多个终端 xff08 准确说是伪终端 xff09 使用该工具 xff0c 用户可以连接或
  • css小技巧之浮动,居中,周围阴影,relative妙用

    css在布局和样式微调中 xff0c 有很多小技巧 xff0c 今天总结一些小妙招 xff0c 这些方法基本上很好用 xff0c 而且不会轻易弄混淆 我们为了看出效果 xff0c 将页面做了一些修饰 xff0c 比如很多地方加上了边框 xf
  • react+antd动态表单以及数组对象示例

    在实际开发中 xff0c 我们会遇到表单中有些数据项是多个 xff0c 并不是普通的一个值 xff0c 或者一组值 xff0c 而是一个数组 xff0c 比如联系人这一项 xff0c 我们通常会有多个联系人 xff0c 这时候 xff0c
  • notepad++安装c/c++简单编程开发环境

    notepad 43 43 作为一个常用的编辑器 xff0c 加上一些插件可以很方便的作为一个简易的编译运行环境 xff0c 说是简易 xff0c 是因为运行简单的程序或者demo可以很方便 xff0c 如果大型的项目 xff0c 还是通过
  • 去掉webpack脚手架构建的vue项目中的eslint检查

    eslint是一个语法格式检测的工具 xff0c 对于规范开发有好处 xff0c 培养严格的书写习惯 xff0c 但是对于新手来说 xff0c 非常的痛苦 xff0c 有时候没有语法错误 xff0c 仅仅是格式中tab space区分不严格
  • Vue中百度地图的应用

    百度地图对于vue项目也做了依赖 xff0c 他就是vue baidu map xff0c 我们在vue项目中 xff0c 只需要安装vue baidu map依赖即可使用 xff0c 另外 xff0c 百度地图javascript api
  • React Hook “useState“ is called in function “xxx“ which is neither a React function component or解决办法

    如题所示 xff0c 在React开发中 xff0c 我们会自定义一些函数 xff0c 比如hook函数 xff0c 或者组件 xff0c 当我们使用了useState useEffect等这些hook函数的时候 xff0c 可能会报错 x
  • electron+vue项目安装vue-devtools插件

    这里记录一下自己安装过程中遇到的问题 xff1a 1 首先需要安装vue devtools xff0c 遇到了源码编译构建的时候的webpack webpack cli反复提示缺失的问题 这个问题很烦 a git clone https g
  • vue+vuetify表格控件v-data-table使用自定义列渲染

    这里先说明一下vue项目中使用vuetify框架进行整合的办法 xff1a 1 加入依赖 npm install vuetify save 2 加入开发依赖 npm install sass sass loader deepmerge sa
  • vue+vuetify构建简单消息确认框

    vue框架自己好像没有弹出框 xff0c 而vuetify有弹出框v dialog xff0c 没有确认框confirm xff0c 虽然确认框本身就是弹出框 xff0c 但是弹出框的功能有个特点 xff0c 就是确定做一件事情 xff0c
  • docker-compose构建mysql服务

    docker安装mysql服务显得很快捷 xff0c 我们如果使用了docker compose那就更快了 xff0c 我们只需要按照我们的要求 xff0c 设置相应的端口映射 xff0c 如果有需求 xff0c 也可以设置数据映射 配置如
  • Nginx核心模块内置变量

    本文根据Nginx官网整理了Nginx的ngx http core module模块的内置变量 xff0c 可与Apache做对比参考 随后做了一次测试观察各变量的值 xff0c 并附上测试结果 1 变量列表 arg name 请求行中参数
  • js属性名用变量代替

    在前端中 xff0c 我们有时候需要利用变量名来设置属性名 xff0c 虽然不是很常见 xff0c 但是也是一个应用场景 这时候 xff0c 我们如果想当然的 xff0c 直接使用变量来设置 xff0c 那么可能不会达到我们想要的结果的 我
  • nodejs利用ffi库调用windows系统user32库函数获取桌面程序窗口大小

    ffi库是npm提供的操作windows系统库函数的依赖库 xff0c 安装过程会比较麻烦 xff0c 需要编译 xff0c 可能需要npm全局安装windows build tools xff0c 如何安装 xff0c 可以参照这里 这篇
  • nodejs利用ffi库调用windows系统user32函数模拟用户登录操作

    如题所示 xff0c 一般的桌面程序 xff0c 用户登录很简单 xff0c 就是找到用户名和密码输入框 xff0c 输入相应的用户名和密码 xff0c 然后点击 登录 按钮 xff0c 完成登录操作 这是人为操作的步骤 xff0c 如果这
  • 通过vue指令创建electron-vue模板项目出现一直“downloading template“问题

    今天试了一下 xff0c vue init simulatedgreg electron vue vueapp的时候 xff0c 在命令行下一直downloading template xff0c 让我很懊恼 原来vue init创建的时候
  • electron-vue与vuetify整合出现报错:If you‘re seeing “$attrs is readonly“

    如题所示 xff0c 正常情况下electron vue与vuetify的整合 xff0c 因为就是vue与vuetify的整合 xff0c 按照一般的推荐方法 xff0c 基本不会出错 xff0c 但是 xff0c 这里因为electro
  • VISA编程实例(C实现)

    今天写这个文章 xff0c 是因为自己工作中用到了ROHDE amp SCHWARZ xff08 即罗德 施瓦茨公司 xff09 的仪表设备 xff0c 需要通过编程的方式来读取仪表上功率测试结果 xff0c 本来仪表上显示了测试结果 xf
  • mac下通过gcc命令手动编译动态链接库示例

    编译动态链接库 xff0c windows linux mac平台各不相同 xff0c 从文件上来说 xff0c windows下是dll xff0c linux下是so xff0c mac下是dylib xff1b 命令上也会有区别 xf
  • c++中char[]与char*的转换以及char*与数字互转

    在c c 43 43 中 xff0c 字符串操作不可避免 xff0c 而且通常 xff0c char 或者char 就能表示字符串 xff0c 这个跟java语言有很大的差别 xff0c java中char是字符 xff0c string才