C++ 中几种类型相互转换

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