Zodiac Wang
  • Home
  • Categories
  • Tags
  • Archives

C++中几种类型之间的相互转换

Table of Contents

  • 1  1.string 转 int 等
    • 1.1  (1) 利用 stringstream
    • 1.2  (2) 利用 C++ 函数 stoi() 等
  • 2  2. int 等转换为 string
    • 2.1  (1) 利用 stringstream
    • 2.2  (2) 利用 C++ 11 新特性 to_string() 函数
  • 3  3. string 转换为 C 字符串
    • 3.1  (1) 利用 stringstream
    • 3.2  (2) 利用 string 类的成员函数 c_str()
  • 4  4. C 字符串转换为 string
    • 4.1  (1) C++ 已对 string 进行了重载 可以在定义时直接初始化,或者赋值
    • 4.2  (2) 也可使用 stringstream
  • 5  5. C 字符串转换为 int 等
    • 5.1  (1) 利用 stringstream
    • 5.2  (2) 利用 C 函数 atoi 等
    • 5.3  (3) 利用 sscanf
    • 5.4  (4) 利用 C 函数 strtol
  • 6  6. int 等转换为 C 字符串
    • 6.1  (1) 利用 stringstream
    • 6.2  (2) 利用 sprintf
  • 7  注:

1.string 转 int 等¶

(1) 利用 stringstream¶

// string to long
long str2long(string& str)
{
    stringstream ss;
    long i;
    ss << str;
    ss >> i;
    return i;
}

(2) 利用 C++ 函数 stoi() 等¶

//string 2 loog
long str2long(string& str)
{
    long l =  stoi(str);
    return l;
}
//str2float
float str2float(string& str)
{
    float f = stof(str);
    return f;
}

2. int 等转换为 string¶

(1) 利用 stringstream¶

string long2str(long l)
{
    string str;
    stringstream ss;
    ss << l;
    str = ss.str();
    //ss >> str;
    return str;
}

(2) 利用 C++ 11 新特性 to_string() 函数¶

string long2str(long l)
{
    string str = to_string(1);
    return str;
}

3. string 转换为 C 字符串¶

(1) 利用 stringstream¶

void* string2chars(string& str, char* ch)
{
    stringstream ss;
    ss << str;
    ss >> ch;
}
//char 数组长度不做考虑

(2) 利用 string 类的成员函数 c_str()¶

注意不能直接用 const char 对 char 类型进行初始化或赋值

void string2chars(string& str, char* ch)
{
    //char* ch = str.c_str();
    //无法将 用 const char* 对 char* 实例进行初始化
    strcpy(ch, str.c_str());
}

4. C 字符串转换为 string¶

(1) C++ 已对 string 进行了重载 可以在定义时直接初始化,或者赋值¶

此时 C 字符串分为两种,一种是 "abc" 这种 const char*, 另一种是 char 数组,即 char*

//对于 const char*
string chars2string(const char* ch)
{
    string str(ch);
    //string str = ch;
    //string str;
    //str = ch;
    return str;
}

//对于 char*
string chars2string(char* ch)
{
    string str(ch);
    //string str = ch;
    //string str;
    //str = ch;
    return str;
}

实际上区别就是 没有从 const char* 到 char* 的自动转换

(2) 也可使用 stringstream¶

5. C 字符串转换为 int 等¶

(1) 利用 stringstream¶

long chars2long(char* ch)
{
    stringstream ss;
    long l;
    ss << ch;
    ss >> l;
    return l;
}

(2) 利用 C 函数 atoi 等¶

long chars2long(char* ch)
{
    int i = atoi(ch);
    return i;
}

(3) 利用 sscanf¶

long chars2long(char* ch)
{
    int i;
    sscanf("17","%D",&i); // 17
    //sscanf("17","%X",&i); // 23
    //sscanf("0X17","%X",&i); // 23
    return i;
}

(4) 利用 C 函数 strtol¶

原型

long int strtol (const char* str, char** endptr, int base);

strtol() 函数用来将字符串转换为长整型数(long).

str 为要转换的字符串,endstr 为第一个不能转换的字符的指针,base 为字符串 str 所采用的进制。

运行原理:strtol() 会将参数 str 字符串根据参数 base 来转换成长整型数(long)。参数 base 范围从2 至36,或0。参数base 代表 str 采用的进制方式,如base 值为10 则采用10 进制,若base 值为16 则采用16 进制等。

strtol() 会扫描参数 str 字符串,跳过前面的空白字符(例如空格,tab缩进等,可以通过 isspace() 函数来检测),直到遇上数字或正负符号才开始做转换,再遇到非数字或字符串结束时('\0')结束转换,并将结果返回。

注意:

当 base 的值为 0 时,默认采用 10 进制转换,但如果遇到 '0x' / '0X' 前置字符则会使用 16 进制转换,遇到 '0' 前置字符则会使用 8 进制转换。 若endptr 不为NULL,则会将遇到的不符合条件而终止的字符指针由 endptr 传回;若 endptr 为 NULL,则表示该参数无效,或不使用该参数。

返回值:

返回转换后的长整型数;如果不能转换或者 str 为空字符串,那么返回 0(0L);如果转换得到的值超出 long int 所能表示的范围,函数将返回 LONG_MAX 或 LONG_MIN(在 limits.h 头文件中定义),并将 errno 的值设置为 ERANGE。

实际上:

ANSI C 规范定义了 stof()、atoi()、atol()、strtod()、strtol()、strtoul() 共6个可以将字符串转换为数字的函数。另外在 C99 / C++11 规范中又新增了5个函数,分别是 atoll()、strtof()、strtold()、strtoll()、strtoull()。

long chars2long(char* ch, int base)
{
    char* end = nullptr;
    long l = strtol(ch, &end, base);
    return l;
}

6. int 等转换为 C 字符串¶

(1) 利用 stringstream¶

void int2chars(int i, char* ch)
{
    stringstream ss;
    ss << i;
    ss >> ch;
}

(2) 利用 sprintf¶

void int2chars(int i, char* ch)
{
    sprintf(ch,"%d", i);
}

注:¶

1.stringstream 总体来说是不够智能的,例如

stringstream ss;
int i;
ss << "hello world";
ss >> i;

这样的代码是可以无异常运行的,如果想做出改变可以选择使用 Boost 库中的转换方法,不过一般情况下 Boost 太过复杂并不是一个很好的选择。

虽然 stringstream 在某些情况下不安全,但至少在内存管理方面是相对安全的,不像 atoi atol 或者 printf sprintf 等函数一样,不对内存进行任何安全检测

2.将 const 字符串 转换为 字符串

使用 sprintf()

int sprintf ( char * str, const char * format, ... );

sprintf 在打印字符串时,会自动在后一内存块上补 '\0',但是并不会对这块内存是否溢出进行检测。

此时可以使用 sprintf 的安全版本,sprintf_s

int sprintf_s(char *buffer, size_t sizeOfBuffer, const char *format [,argument]...);

通过指定缓冲区长度来避免sprintf()存在的溢出风险

参考:

strtol


  • « C++派生类中的函数覆盖和重载
  • cin-cinget-cingetline的区别 »

Published

5 18, 2019

Category

posts

Tags

  • cpp 8

Contact

  • Zodiac Wang - A Fantastic Learner
  • Powered by Pelican. Theme: Elegant