跳至主要內容

char, char*, char[], int的区别、互转及字符串操作 - C语言笔记

Kamimika...大约 7 分钟C语言C语言字符串类型转换笔记

类型转换一直是 C 语言编程中的难点和痛点,本文将介绍 C 语言中 char, char *, char [], int 之间的区别、互转以及一些常见的字符串操作。

一、char 与 int 互转: 直接赋值

charint可以直接互转,但是需要注意的是,char的范围是 0~255 或 -128~127,而int的范围是-2147483648~2147483647。

char c1 = 'a';
int i = c1;
char c2 = i;

二、char* 与 int 互转

2.1 int 转 char*: sprintf()

  • 方法一:itoa(int value, char* str, int base)函数可以将整数valuebase进制的形式转换为字符串,并存储到str所指的字符数组中。

  • 方法二:char* itoa(int value, NULL, int base)函数可以将整数valuebase进制的形式转换为字符串,并返回一个指向该字符串的指针。

  • 方法三(推荐):sprintf(char* str, "%d", value)格式化字符串函数可以将整数value以十进制的形式转换为字符串,并存储到str所指的字符数组中。

int value = 123;
char *str;
sprintf(str, "%d", value);
printf("%s\n", str); // 123

提示

理论上itoa()位于<stdlib.h>头文件中。 但itoa()可能不被编译器支持。

2.2 char* 转 int: atoi(), strtol()

  • 方法一:int atoi(char* str)函数可将字符串str转换为整数(仅支持的最大整数值为INT_MAX)。

  • 方法二(推荐):int strtol(char* str, char** endptr, int base)函数可将字符串str逐位转换为整数直到遇到非数字字符或字符串结束,返回转换后的整数值(仅支持的最大整数值为INT_MAX),并将遇到的非数字字符的地址存储到endptr所指的指针中。 可通过判断*endptr是否为NULL(即endptr是否指向空指针)来判断整个字符串是否都转换成功。

例如:

char str[] = "123abc";
char *endptr;
int num = strtol(str, &endptr, 10);
printf("%d\n", num); // 123
printf("%p\n", endptr); // 0xff114514
printf("%c\n", *endptr); // a

提示

atoi(), strtol()都位于<stdlib.h>头文件中。

三、char* 字符串操作

3.1 获取字符串长度 strlen()

strlen(const char* str)函数可以获取字符串str的长度。

原理就是遍历字符串直到遇到'\0'结束,并返回遍历的次数。

因此并不一定等于实际分配的内存大小。

char str[] = "hello";
int len = strlen(str);
printf("%d\n", len); // 5

3.2 获取字符串已分配空间 sizeof()

sizeof(char str*)sizeof(char str[]):获取str指向的字符串所占的字节数。

注意

由于普通字符串char为 1 个字节,故sizeof(char)可直接与字符串长度相对应而无需转换。 但由于字符串末尾的'\0'字符也占用 1 个字节,故在未指定字符串长度时,sizeof()获取的结果比实际字符串长度多 1。

char str[64] = "hello";
int size = sizeof(str);
printf("%d\n", size); // 64

3.3 字符串拼接 strcat()/strncat()

strcat(char* dest, const char* src)src指向的字符串拼接到dest指向的字符串的尾部。

strncat(char* dest, const char* src, size_t n)src指向的字符串的前n个字符拼接到dest指向的字符串的尾部。

char str1[64] = "hello, ";
char str2 = "world";

strcat(str1, str2);
printf("%s\n", str1); // hello, world
char str1[64] = "hello, ";
char str2 = "world";

strncat(str1, str2, 2);
printf("%s\n", str1); // hello, wo

注意 (仅 C 语言)

如果dest是直接赋值的指针类型(char *str = "...")而不是数组类型(char str[]),执行strcat()可能会导致访问未分配的空间而出现段错误。 (Segmentation fault (core dumped))

然而,如果是数组类型(char str[]),虽然不会报错,但是可能导致内存溢出从而修改其它变量的值

例如:

char *str1 = "hello, ";
char str2[] = "world";
strcat(str1, str2); // 错误,未分配足够的空间容纳str2字符串

改为数组类型后:

char str1[] = "hello, "; // 栈高位地址
char str2[] = "world"; // 栈低位地址
strcat(str1, str2); // 正确,不会报错
printf("%s\n", str1); //hello, world
printf("%s\n", str2); //world
char str2[] = "world"; // 栈高位地址
char str1[] = "hello, "; // 栈低位地址
strcat(str1, str2); // 正确,不会报错,但覆盖了高位的数据
printf("%s\n", str1); //hello, world
printf("%s\n", str2); //olld
strcat前后的栈内存布局(strcat行为比较迷惑)
strcat前后的栈内存布局(strcat行为比较迷惑)

改为指向数组类型的指针是同样的结果:

char str[] = "hello, ";
char *str1 = str;
char str2[] = "world";
strcat(str1, str2); // 正确,不会报错

3.4 字符串复制 strcpy()/strncpy()

strcpy(char* dest, const char* src)函数将src指向的字符串复制(覆盖)到dest指向的字符串中。

strncpy(char* dest, const char* src, size_t n)函数将src指向的字符串的前n个字符复制(覆盖)到dest指向的字符串中。

char str1[64] = "hello,";
char str2[] = "world";

strcpy(str1, str2);
printf("%s\n", str1); //world
char str1[64] = "hello,";
char str2[] = "world";

strncpy(str1, str2, 5);
printf("%s\n", str1); //world,

strncpy(str1, str2, 6); // 末尾的'\0'字符也会被复制
printf("%s\n", str1); //world

注意

strcat()类似,如果dest是直接赋值的指针类型(char *str = "...")而不是数组类型(char str[]),执行strcpy()可能会导致访问未分配的空间而出现段错误。 (Segmentation fault (core dumped))

3.5 字符串比较 strcmp()

int strcmp(const char* str1, const char* str2)函数可以比较str1str2指向的字符串是否相等,并返回一个整数值。
0 表示相等,负数表示str1小于str2正数表示str1大于str2

char str1[] = "hello, ";
char str2[] = "world";

int cmp = strcmp(str1, str2);
if (cmp == 0) {
    printf("str1 == str2\n");
} else if (cmp < 0) {
    printf("str1 < str2\n");
} else {
    printf("str1 > str2\n");
}

3.6 字符串查找 strchr()

char* strchr(const char* str, int c)函数可以查找字符串str中第一个出现字符c的位置,并返回一个指向该位置的指针。

char str[] = "hello, world";
char* p = strchr(str, 'l');
if (p) {
    printf("%s\n", p); // llo, world
} else {
    printf("not found\n");
}

3.7 字符串替换 strstr()

char* strstr(const char* str1, const char* str2)函数可以查找字符串str1中第一次出现字符串str2的位置,并返回一个指向该位置的指针。

char str1[] = "hello, world";
char str2[] = "wo";
char* p = strstr(str1, str2);
if (p) {
    printf("%s\n", p); // world
} else {
    printf("not found\n");
}

3.8 字符串分割 strtok()

char* strtok(char* str, const char* delimiters)函数可以将字符串str按照分隔符delimiters进行分割,并返回一个指向分割后的第一个字符串的指针。

char str[] = "hello, world, goodbye";
char* p = strtok(str, ", ");
while (p) {
    printf("%s\n", p);
    p = strtok(NULL, ", ");
}
// 输出:
// hello
// world
// goodbye

char str[] = "hello, world, goodbye";
for (char *p = strtok(str, ", "); p; p = strtok(NULL, ", "))
  printf("%s\n", p);
// 输出:
// hello
// world
// goodbye

3.9 字符串格式化 sprintf()

printf()函数类似,sprintf()函数可以将格式化字符串format中的占位符替换为实际值,并将结果存储到str指向的字符串中。

具体详见 printf 与 scanf.md

提示

strcat(), strcpy(), strlen(), strcmp(), strchr(), strstr(), strtok(), sprintf()都位于<string.h>头文件中。


C++

注意

以下为 C++ 内容,C 语言没有string类型。
C++中无法通过char *str = "..."的方式创建字符串指针
(ISO C++ forbids converting a string constant to ‘char\*’)

四、string 与 char[] 互转

4.1 char[] 转 string: 直接赋值

char str[] = "hello, world";
string s = str;

char str[] = "hello, world";
char *p = str;
string s = p;

4.2 string 转 char[]: string.c_str()

const char* c_str(const string& str)函数可以将string类型转换为const char*类型。

例如:

string str = "hello, world";
const char *p = str.c_str(); //必须加上const,否则编译器会报错,const char* 无法转换为 char*

五、int 与 string 互转

5.1 int/float/double 转 string: to_string()

string to_string(int value)函数可以将整数value转换为string类型。

例如:

int value = 123;
string s = to_string(value);
cout << s << endl; // 123

5.2 string 转 int: stoi()

int/float stoi(const string& str, nullptr_t* endptr, int base)函数可以将字符串str转换为整数,并返回转换后的整数值。

例如:

string s = "123.456";
int value = stoi(s);
cout << value << endl; // 123

5.3 string 转 float/double: stof()/stod()

float/double stof(const string& str, nullptr_t* endptr)函数可以将字符串str转换为浮点数,并返回转换后的浮点数值。

例如:

string s = "123.456";
float value = stof(s);
cout << value << endl; // 123.456

提示

string类型, to_string(), stoi()都位于<string.h>头文件中。

上次编辑于:
贡献者: wzh
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v3.4.1