字符篇 (以下比较的都是基于ASCII码表中的字符, 中文字符可能会报错, 也可能不会报错)
1. isalnum 判断字符是不是字母或数字
#include <ctype.h>
#include <stdio.h>
int main(void) {
char a = 'A';
int b = isalnum(a);
printf("%d\n", b);
}
输出: 1
#include <ctype.h>
#include <stdio.h>
int main(void) {
char a = 'a';
int b = isalnum(a);
printf("%d\n", b);
}
输出: 2
#include <ctype.h>
#include <stdio.h>
int main(void) {
char a = '5';
int b = isalnum(a);
printf("%d\n", b);
}
输出: 4
#include <ctype.h>
#include <stdio.h>
int main(void) {
char a = ',';
int b = isalnum(a);
printf("%d\n", b);
}
输出: 0
使用 isalnum 总结如下:
1. 如果是大写字母, 则返回值是 1;
2. 如果是小写字母, 则返回值是 2;
3. 如果是数字, 则返回值是 4;
4.如果不是字母或者数字, 则统一返回 0;
2. isalpha 判断是不是字母:
#include <ctype.h>
#include <stdio.h>
int main(void) {
char a = 'A';
int b = isalpha(a);
printf("%d\n", b);
}
输出: 1
#include <ctype.h>
#include <stdio.h>
int main(void) {
char a = 'a';
int b = isalpha(a);
printf("%d\n", b);
}
输出: 2
#include <ctype.h>
#include <stdio.h>
int main(void) {
char a = '5';
int b = isalpha(a);
printf("%d\n", b);
}
输出: 0
使用 isalpha 总结如下:
1. 如果是大写字母, 则返回值是 1;
2. 如果是小写字母, 则返回值是 2;
3. 如果是数字或者符号或者转义符号之类的非字母, 统一返回值是 0;
3. isdigit判断是不是数字:
#include <ctype.h>
#include <stdio.h>
int main(void) {
char a = '8';
int b = isdigit(a);
printf("%d\n", b);
}
输出: 1
使用 isdigit 总结如下:
1. 如果判断的确实是数字, 则返回值是: 1;
2. 非数字, 统一返回值是: 0;
4. ispunct 判断是不是标点符号:
#include <ctype.h>
#include <stdio.h>
int main(void) {
char a = '@';
int b = ispunct(a);
printf("%d\n", b);
}
输出: 16
使用ispunct总结如下:
1. 如果是标点符号, 则输出: 16;
2. 如果是转义字符或者字母数字之类的非标点符号, 统一输出: 0;
5. isspace 判断是不是空格:
#include <ctype.h>
#include <stdio.h>
int main(void) {
char a = ' ';
int b = isspace(a);
printf("%d\n", b);
}
输出: 8
使用isspace总结如下:
1. 如果是空格, \n, \r, \f, \t, 等等空格符号, 统一输出: 8;
2. 其他非空字符, 统一输出: 0
6. islower 判断是不是小写字母:
#include <ctype.h>
#include <stdio.h>
int main(void) {
char a = 'a';
int b = islower(a);
printf("%d\n", b);
}
输出: 2
使用 islower 总结如下:
1. 如果是小写字母, 统一输出: 2;
2. 如果是非小写字母, 统一输出: 0;
7. isupper 判断是不是大写字母:
#include <ctype.h>
#include <stdio.h>
int main(void) {
char a = 'A';
int b = isupper(a);
printf("%d\n", b);
}
输出: 1
使用 isupper 总结如下:
1. 如果是大写字母, 则返回值是: 1;
2. 如果是非大写字母, 则返回值是: 0;
字符串篇:
1. strlen 获取字符串长度:
#include <stdio.h>
#include <string.h>
int main(void) {
char *a = "hello world";
int b = strlen(a);
printf("%d\n", b);
}
输出: 11
使用 strlen 总结如下:
返回的是字符串的长度, 包括最后面的末尾结束标志符吗?不包括, 要注意末尾必须要有'\0'结束符才可以使用此函数;
2. strcat , strncat 合并字符串:
#include <stdio.h>
#include <string.h>
int main(void) {
char a[20] = "hello ";
char *b = "world!";
strcat(a, b);
printf("%s\n", a);
}
输出结果:
hello world!
#include <stdio.h>
#include <string.h>
int main(void) {
char a[20] = "hello ";
char *b = "world!";
strncat(a, b, 14);
printf("%s\n", a);
}
hello world!
使用 strcat 与 strncat 总结如下:
1. strcat(a, b) 的意思是将b拼接到a数组的剩余空间内部, a其中, 它会自动将a原有的'\0'去掉
2. 如果能够明确a的剩余空间装的下b, 那么就尽情的享受strcat, 但是, 但是, 如果不明确装不装的下, 建议使用strncat, 末尾放入可用空间给他, 如果可用空间满了, 他就不会强行范围未定义的空间, 这样就避免了程序的错误, 格式如下: strncat(a, b, 剩余可用空间);
3. strcmp, strncmp 可以判断两个字符串是否相同:
#include <stdio.h>
#include <string.h>
int main(void) {
char *a = "hello world!";
char *b = "hello world!";
int c;
c = strcmp(a, b);
printf("%d\n", c);
}
输出:
0
#include <stdio.h>
#include <string.h>
int main(void) {
char a[10] = {'a', 'b', 'c', 'd'};
char b[10] = {'a', 'b', 'c', 'd', '\0'};
int c;
c = strcmp(a, b);
printf("%d\n", c);
}
输出:
0
再看几个:
#include <stdio.h>
#include <string.h>
int main(void) {
char *a = "a";
char *b = "b";
int c;
c = strcmp(a, b);
printf("%d\n", c);
}
输出:
-1
#include <stdio.h>
#include <string.h>
int main(void) {
char *a = "a";
char *b = "A";
int c;
c = strcmp(a, b);
printf("%d\n", c);
}
输出:
1
对照ASCII码表:
发现, "a" 在 "b" 前面, 所以输出 -1
"a" 在 "A" 后面, 所以输出 1
因为"hello world!" 与 "hello world!" 相同, 所以输出 0
因为 {'a', 'b', 'c', 'd'} 与 {'a', 'b', 'c', 'd', '\0'} 除了'\0' 外相同, 所以输出0
再看一个, 稍后总结:
#include <stdio.h>
#include <string.h>
int main(void) {
char *a = "hello python!";
char *b = "hello c!";
int c;
c = strcmp(a, b);
printf("%d\n", c);
}
输出:
1
因为 "p" 在 "c" 的后面, 所以输出 1
#include <stdio.h>
#include <string.h>
int main(void) {
char *a = "hello python!";
char *b = "hello c!";
int c;
c = strncmp(a, b, 6);
printf("%d\n", c);
}
输出:
0
解读: c = strncmp(a, b, 6);
意思是: 比较a与b的前6位字符是否相同, 相当于是只是比较了"hello " 与 "hello ", 所以相等, 既然相等, 所以c是0
总结如下:
1. 对于strcmp(a, b)来说: 如果a 在 b 的前面(ASCII码表的前面), 那么返回值就是-1, 我把它称为以小比大为-1
2. 对于strcmp(a, b)来说, 如果 a 在 b 的后面(ASCII码表的后面), 那么返回值就是1, 我把它称为以大比小为+1
3. 对于strcmp(a, b)来说, 如果 a 与 b 相等(strcmp不会看你有没有'\0', 至少它不会以此为依据对比吧, 猜的!), 那么返回值就是0
4. 对于strncmp(a, b, n)来说, 也有上述属性, 但还有一个比较牛逼的, 体现在n这里, 比较的是 a 与 b 的前n个元素, 注意是从开头到第n个元素, 用下表来说就是[0, n)
基于上面, 写了个小小的字符串排序函数:
#include <stdio.h>
#include <string.h>
char *sort_big(char *p);
char *sort_small(char *p);
int main(void) {
char a[20] = "a1b2c3d4A5B6C7D8";
char b[20] = "a1b2c3d4A5B6C7D8";
sort_big(a);
sort_small(b);
puts(a);
puts(b);
}
char *sort_small(char *p) {
int a, b;
char change;
for (a = 0;; a++) {
if (p[a] == '\0')
goto out;
for (b = a + 1;; b++) {
if (p[b] == '\0')
goto lets;
else if (strcmp(&p[a], &p[b]) > 0) {
change = p[a];
p[a] = p[b];
p[b] = change;
}
}
lets:;
}
out:;
return p;
}
char *sort_big(char *p) {
int a, b;
char change;
for (a = 0;; a++) {
if (p[a] == '\0')
goto out;
for (b = a + 1;; b++) {
if (p[b] == '\0')
goto lets;
else if (strcmp(&p[b], &p[a]) > 0) {
change = p[a];
p[a] = p[b];
p[b] = change;
}
}
lets:;
}
out:;
return p;
}
输出:
dcbaDCBA87654321
12345678ABCDabcd
花里胡巧吧-_-
4. strchr 与 strstr 查询最近字符或字符串的地址:
#include <stdio.h>
#include <string.h>
int main(void) {
char *a = "hello python!";
char *b = "how old are you!!!";
char *c, *s;
c = strchr(a, 'o');
s = strstr(b, "are");
printf("%p\t%c\n%p\t%c", c, *c, s, *s);
}
输出:
0000000000404004 o
0000000000404016 a
使用 strchr 与 strstr 的总结如下:
strchr 与 strstr 返回的是都是一个地址, 都是最先找到的那个元素的地址,
5. 使用 atoi, atof, atol, strtol, strtoul, strtod 来将一些数字字符串转成真字符串(在stdlib.h里面, 好像)
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char *a = "12";
int b = atoi(a);
printf("%d\n", b);
}
输出:
12
atoi, 可以把它读成: alpha to int, 将字符串转成int类型数据, 只会从开头部分开始检索整数, 直到不能构成整数为止!
可以看一下这个理解一下:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char *a = "12c";
int b = atoi(a);
char *x = "c12";
int y = atoi(x);
printf("%d\n%d\n", b, y);
}
12
0
从开头开始找, 找得到就输出, 找不到就返回0
atof 与 atoi 类似, 找的是double类型的内容,
atol 也与 atoi 类似, 找的是long类型数据,
重点讲一下strtol, strtod, strtoul
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char *a = "12515151";
char *end;
long b = strtol(a, &end, 10);
printf("%d\n%d\n", b, *end);
}
先简单了解一下: b = strtol(a, &end, 10);
意思是: 将a里面开头部分的整数字符串转换成10进制的long类型数据, 并且这个end代表的是第一个匹配不到整数的地址, 即末尾的'\0'的地址, 打印这里的*end, 它的值就是'\0'对应的ASCII码表的整数值, 也就是 0;
再看一个例子, 加深理解:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char *a = "12515151jasbckhkah";
char *end;
long b = strtol(a, &end, 10);
printf("%d\n%d\n%c\n", b, *end, *end);
}
输出结果为:
12515151
106
j
strtol从开头一直匹配直到出现一个东西不满足long类型数据为止, 并把这个不满足条件的第一个东西的地址发送给end, 所以这个end最终就指向了 'j' ASCII码表就是106, 再来观察一下:
strtol(a, &end, 10); 第一个参数就是首字符串的地址(可以不是首字符串, 如果不是首地址, 那么匹配时就从这里开始往后面匹配!), 第二个参数就是字符指针的地址, 用于储存不满足条件的第一个字符的地址, 最后一个参数就是进制, 10进制就输入10
strtod 是 str to double, strtoul 是 str to unsigned long, 功能与上面差不多
6. sprintf格式化字符串操作:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char *a = "https://bizhi.ijinshan.com/2/index_%d.shtml";
char b[50];
for (int i = 1; i < 239; i++) {
sprintf(b, a, i);
printf("%s\n", b);
}
}
输出结果:
https://bizhi.ijinshan.com/2/index_1.shtml
https://bizhi.ijinshan.com/2/index_2.shtml
https://bizhi.ijinshan.com/2/index_3.shtml
https://bizhi.ijinshan.com/2/index_4.shtml
https://bizhi.ijinshan.com/2/index_5.shtml
https://bizhi.ijinshan.com/2/index_6.shtml
https://bizhi.ijinshan.com/2/index_7.shtml
https://bizhi.ijinshan.com/2/index_8.shtml
.
.
.
.
.
.
太多了, sprintf类似于printf, 只不过一个是格式化字符串, 一个是格式化输出
sprintf(b, "https://bizhi.ijinshan.com/2/index_%d.shtml", 4);
对比一下printf:
printf( "https://bizhi.ijinshan.com/2/index_%d.shtml", 4);
挺好用的。