字符串处理
1、字符串输入/输出
字符串输出
-
putchar
-
将一个字符(一个无符号字符)、一个介于0到127之间的十进制数(表示ASCII码中的字符),或一个char类型的变量输出到标准输出设备。
-
#include <stdio.h>
int putchar(int c);-
c:需要进行输出的字符
-
返回值:出错将返回 EOF
-
-
-
puts
-
把字符串输出到标准输出设
备,将’ \0 ‘转换为换行符’ \n ’- 自行换行
-
#include <stdio.h>
int puts(const char *s);-
s:需要进行输出的字符串
-
返回值:成功返回一个非负数;失败将返回 EOF,EOF 其实就是-1
-
-
如果只是单纯输
、出字符串到标准输出设备,而不包含数字格式化转换操作,那么使用 puts()会更加方便、简洁
-
-
fputc
-
fputc()与 putchar()类似,也用于输出参数 c 指定的字符(一个无符号字符),与 putchar()区别在于,putchar()只能输出到标准输出设备,而 fputc()可把字符输出到指定的文件中
- 可以是标准输出、标准错误设备,也可以是一个普通文件
-
#include <stdio.h>
int fputc(int c, FILE *stream);-
c:需要进行输出的字符
-
stream:文件指针
-
返回值:成功时返回输出的字符;出错将返回 EOF
-
-
-
fputs
-
fputs()与 puts()类似,也用于输出一条字符串,与 puts()区别在于,puts()只能输出到标准输出设备,而 fputs()可把字符串输出到指定的文件中
- 需要字符串自己写入换行符
-
#include <stdio.h>
int fputs(const char *s, FILE *stream);-
s:需要输出的字符串
-
stream:文件指针
-
返回值:成功返回非负数;失败将返回 EOF
-
-
-
与printf比较
-
printf()可以按照自己规定的格式输出字符串信息,称为格式化输出
-
putchar()、puts()、fputc()、fputs()这些函数只能输出字符串,不能进行格式转换
-
但是 putchar()、puts()、fputc()、fputs()这些库函数相比与 printf,在使用上方便、简单
-
与 printf()一样,putchar()、puts()、fputc()、fputs()这些函数也是标准 I/O 函数,属于标准 C 库函数
-
字符串输入
-
gets
-
从标准输入设备(譬如键盘)中获取用户输入的字符串
-
不能直接用于读取整数、浮点数或单个字符数据类型
- 如果用户输入了 “123”,gets() 会存储字符 ‘1’,‘2’,‘3’,和一个终止的空字符 ‘\0’
-
-
#include <stdio.h>
char *gets(char *s);-
s:指向字符数组的指针,用于存储字符串
-
返回值:如果成功,该函数返回指向 s 的指针;如果发生错误或者到达末尾时还未读取任何字符,则返回 NULL
-
-
gets()函数允许输入的字符串带有空格、制表符
-
当从输入缓冲区中读走字符后,相应的字符便不存在于缓冲区了
-
gets()函数不检查缓冲区溢出
-
一般建议大家不要使用这个函数,可以使用后面将给大家介绍的 fgets()代替
-
-
getchar
-
从标准输入设备中读取一个字符(一个无符号字符)
-
#include <stdio.h>
int getchar(void);-
无需传参
-
返回值:该函数以无符号 char 强制转换为 int 的形式返回读取的字符,如果到达文件末尾或发生读错误,则返回 EOF
-
-
从输入缓冲区读取字符数据,但只读取一个字符,包括空格、TAB 制表符、换行回车符等
- 即使输入了多个字符,但 getchar()仅读取一个字符
-
-
fgetc
-
fgetc()与 getchar()一样,用于读取一个输入字符
-
#include <stdio.h>
int fgetc(FILE *stream);-
stream:文件指针
-
返回值:该函数以无符号 char 强制转换为 int 的形式返回读取的字符,如果到达文件末尾或发生读错误,则返回 EOF
-
-
fgetc()与 getchar()的区别在于,fgetc 既可以从标准输入设备输入字符,也可以从一个普通文件中输入字符,其它方面与 getchar 函数相同
-
-
fgets
-
即使输入了多个字符,但 getchar()仅读取一个字符
-
#include <stdio.h>
char *fgets(char *s, int size, FILE *stream);-
s:指向字符数组的指针,用于存储字符串
-
size:这是要读取的最大字符数
-
stream:文件指针
- stdin 是一个预定义的宏,代表标准输入流。在大多数系统中,标准输入通常是键盘输入
-
-
使用 fgets()读取文件中输入的字符串,文件指针会随着读取的字节数向前移动
-
fgets()与 gets()的区别主要是三点
-
fgets()既可以从标准输入设备获取字符串、也可
以从一个普通文件中获取输入字符串 -
fgets()可以设置获取字符串的最大字符数
-
gets()会将缓冲区中的换行符’\n’读取出来、将其丢弃、将’\n’替换为字符串结束符’\0’;fgets()并不丢弃,而是作为字符串组成字符存在,并自动在最后添加字符串结束字符’\0’
-
-
-
与scanf比较
-
scanf()格式化输入函数
-
对于%s读入时,空格被视为字符串分割符
-
对于%c 读入时,空格、换行符、TAB 这些都是正常字符
-
-
scanf()与 gets()、getchar()、fgetc()、fgets()这些函数相比,在功能上确实有它的优势,但是在使用上不如它们方便、简单、更易于使用
-
与 scanf()一样,gets()、getchar()、fgetc()、fgets()这些函数也是标准 I/O 函数,属于标准 C 库函数
-
补充
- stdout代表标准输出流,stdin 代表标准输入流,是一个指向FILE类型的指针
2、字符串长度
计算字符串长度的函数
-
strlen()
-
#include <string.h>
size_t strlen(const char *s);-
s:需要进行长度计算的字符串,字符串必须包含结束字符’ \0 ’
-
返回值:返回字符串长度(以字节为单位),字符串结束字符’ \0 '不计算在内
-
-
-
sizeof 和 strlen 的区别
-
sizeof 是 C 语言内置的操作符关键字,而 strlen 是 C 语言库函数
-
sizeof 仅用于计算数据类型的大小或者变量的大小,而 strlen 只能以结尾为’ \0 '的字符串作为参数
-
编译器在编译时就计算出了 sizeof 的结果,而 strlen 必须在运行时才能计算出来
-
sizeof 计算数据类型或变量会占用内存的大小,strlen 计算字符串实际长度
-
3、字符串拼接、拷贝、内存填充
字符串拼接
-
C 语言函数库中提供了 strcat()函数或 strncat()函数用于将两个字符串连接(拼接)
-
strcat
-
#include <string.h>
char *strcat(char *dest, const char *src);-
dest:目标字符串
-
src:源字符串
-
返回值:返回指向目标字符串 dest 的指针
-
-
把 src 所指向的字符串追加到 dest 所指向的字符串末尾,所以必须要保证 dest 有足够的存
储空间来容纳两个字符串,否则会导致溢出错误;dest 末尾的’ \0 '结束字符会被覆盖,src 末尾的结束字符 ’ \0 '会一起被复制过去
-
-
strncat
-
strncat()与 strcat()的区别在于,strncat 可以指定源字符串追加到目标字符串的字符数量
-
#include <string.h>
char *strncat(char *dest, const char *src, size_t n);-
dest:目标字符串
-
src:源字符串
-
n:要追加的最大字符数
-
返回值:返回指向目标字符串 dest 的指针
-
-
当源字符串src至少有n个字符时,函数strncat()会将src中的前n个字符以及一个结束符’\0’添加到目标字符串dest的末尾,总共追加n+1个字节
-
-
字符串拷贝
-
C 语言函数库中提供了 strcpy()函数和 strncpy()函数用于实现字符串拷贝
-
strcpy
-
#include <string.h>
char *strcpy(char *dest, const char *src);-
dest:目标字符串
-
src:源字符串
-
返回值:返回指向目标字符串 dest 的指针
-
-
将源字符串src(必须包括结束字符’\0’)复制到目标字符串dest。使用该函数时,必须确保dest指向的内存空间足够大,以容纳整个src字符串及其结束字符,否则可能会发生内存溢出错误。
-
-
strncpy
-
strncpy()与 strcpy()的区别在于,strncpy()可以指定从源字符串 src 复制到目标字符串 dest 的字符数量
-
#include <string.h>
char *strncpy(char *dest, const char *src, size_t n);-
dest:目标字符串
-
src:源字符串
-
n:从 src 中复制的最大字符数
-
返回值:返回指向目标字符串 dest 的指针
-
-
将字符串从src复制到dest,但不超过n个字符。如果n小于等于源字符串长度,复制的结果不会包含终止字符\0。如果n大于源字符串长度,终止字符\0会被复制。必须确保dest有足够的空间容纳复制的字符,否则会发生溢出错误。
-
-
-
除了strcpy()和strncpy()外,还可以使用memcpy()、memmove()和bcopy()这些库函数进行字符串拷贝,因为字符串拷贝实质上是内存数据的拷贝。这些函数在编程中常用,使用简单,但需注意目标和源内存空间是否重叠。具体用法可通过man手册查询。
内存填充
-
memset
-
用于将某一块内存的数据全部设置为指定的值
-
#include <string.h>
void *memset(void *s, int c, size_t n);-
s:需要进行数据填充的内存空间起始地址
-
c:要被设置的值,该值以 int 类型传递
-
n:填充的字节数
-
返回值:返回指向内存空间 s 的指针
-
-
memset()
函数接受参数c
作为int
类型,但在填充内存时,会将其转换为unsigned char
类型,并以字节为单位进行填充。
-
-
bzero
-
将一段内存空间中的数据全部设置为 0
-
#include <strings.h>
void bzero(void *s, size_t n);-
s:内存空间的起始地址
-
n:填充的字节数
-
返回值:无返回值
-
-
4、字符串比较与查找
字符串比较库函数
-
strcmp
-
#include <string.h>
int strcmp(const char *s1, const char *s2);-
s1:进行比较的字符串 1
-
s2:进行比较的字符串 2
-
返回值:
- ⚫ 如果返回值小于 0,则表示 str1 小于 str2
⚫ 如果返回值大于 0,则表示 str1 大于 str2
⚫ 如果返回值等于 0,则表示字符串 str1 等于字符串 str2
- ⚫ 如果返回值小于 0,则表示 str1 小于 str2
-
-
比较两个字符串,通过逐字符比较它们的 ASCII 码值,直到字符不相同或遇到字符串结束符’\0’为止
-
-
strncmp
-
strncmp()与 strcmp()函数一样,也用于对字符串进行比较操作,但最多比较前 n 个字符
-
#include <string.h>
int strncmp(const char *s1, const char *s2, size_t n);-
s1:进行比较的字符串 1
-
s2:进行比较的字符串 2
-
n:最多比较前 n 个字符
-
返回值:
- ⚫ 如果返回值小于 0,则表示 str1 小于 str2
⚫ 如果返回值大于 0,则表示 str1 大于 str2
⚫ 如果返回值等于 0,则表示字符串 str1 等于字符串 str2
- ⚫ 如果返回值小于 0,则表示 str1 小于 str2
-
-
字符串查找
-
strchr
-
查找到给定字符串当中的某一个字符
-
#include <string.h>
char *strchr(const char *s, int c);-
s:给定的目标字符串
-
c:需要查找的字符
-
返回值:返回字符 c 第一次在字符串 s 中出现的位置,如果未找到字符 c,则返回 NULL
-
-
在字符串中从左到右搜索字符c,并返回第一次出现的位置的指针;如果c是字符串结束符’\0’,则返回指向它的指针;如果未找到c,返回NULL
-
-
strrchr
-
strrchr()函数用于在字符串中从后向前查找某字符的首次出现位置并返回指向该位置的指针,如果未找到,则返回NULL。这与strchr()函数的功能相似,不过strchr()是从前向后查找字符。
-
#include <string.h>
char *strrchr(const char *s, int c);-
s:给定的目标字符串
-
c:需要查找的字符
-
返回值:返回字符 c 第一次在字符串 s 中出现的位置,如果未找到字符 c,则返回 NULL
-
-
-
strstr
-
#include <string.h>
char *strstr(const char *haystack, const char *needle);-
haystack:目标字符串
-
needle:需要查找的子字符串
-
返回值:如果目标字符串 haystack 中包含了子字符串 needle,则返回该字符串首次出现的位置;如果未能找到子字符串 needle,则返回 NULL
-
-
在给定的字符串 haystack 中查找第一次出现子字符串 needle 的位置, 不包含结束字符’ \0 ’
-
5、字符串与数字转换
字符串转整形数据
-
将一个字符串转为整形数据,有两个类型
-
数据类型(int、long int、unsigned long 等)
-
不同进制方式表示的数字字符串(八进制、十六进制、十进制)
-
-
atoi、atol、atoll 函数
-
使用 atoi()、atol()、atoll()函数只能转换十进制表示的数字字符串,即 0~9
-
#include <stdlib.h>
int atoi(const char *nptr);
long atol(const char *nptr);
long long atoll(const char *nptr);-
nptr:需要进行转换的字符串
-
返回值:分别返回转换之后得到的 int 类型数据、long int 类型数据以及 long long 类型数据
-
-
从目标字符串中提取数字,忽略开头的空格,从第一个数字或正负号开始转换,直到遇到非数字字符或字符串终止符为止,然后返回转换结果。
-
-
strtol、strtoll 函数
-
将字符串转为 long int 类型数据和 long long ing 类型数据
- strtol() 和 strtoll() 函数能将字符串转换为 long int 和 long long int 类型的数据,它们与 atol() 和 atoll() 的区别在于,strtol() 和 strtoll() 支持将二进制、八进制、十六进制等不同进制表示的字符串转换为整数。
-
#include <stdlib.h>
long int strtol(const char *nptr, char **endptr, int base);
long long int strtoll(const char *nptr, char **endptr, int base);-
nptr:需要进行转换的目标字符串
-
endptr:是一个指向char**类型的指针,用于在strtol()或strtoll()函数中指示字符串中第一个无效字符的位置。如果endptr不是NULL,函数会将无效字符的地址存储在endptr中。如果没有找到数字,函数会将原始的nptr值存储在endptr中并返回0。如果不需要这个信息,可以将endptr设置为NULL。
-
base:用于指定数字的基数,它的取值范围是2到36之间,或者是特殊值0。Base的值决定了字符串转换为整数时允许的字符范围。例如,base为2时只接受’0’和’1’;base为8时接受’0’到’7’;base为16时接受’0’到’9’以及’a’到’f’(表示十六进制,不区分大小写),其中’a’到’z’代表10到35。
-
当base设置为0时,字符串中的"0x"前缀表示以16为基数,而"0"前缀表示以8为基数
-
当base设置为16时,字符串也可以使用"0x"前缀
-
-
返回值:分别返回转换之后得到的 long int 类型数据以及 long long int 类型数据
-
-
目标字符串在进行转换时,会忽略开头的空格或’0’,直到遇到数字字符或正负号(‘+‘或’-’)才开始转换。转换会在遇到非数字字符或字符串结束符(‘\0’)时停止,并返回结果。
-
-
strtoul、strtoull 函数
-
strtoul()返回值类型是 unsigned
long int,strtoull()返回值类型是 unsigned long long int -
#include <stdlib.h>
unsigned long int strtoul(const char *nptr, char **endptr, int base);
unsigned long long int strtoull(const char *nptr, char **endptr, int base);-
nptr:需要进行转换的目标字符串
-
endptr:是一个指向char**类型的指针,用于在strtol()或strtoll()函数中指示字符串中第一个无效字符的位置。如果endptr不是NULL,函数会将无效字符的地址存储在endptr中。如果没有找到数字,函数会将原始的nptr值存储在endptr中并返回0。如果不需要这个信息,可以将endptr设置为NULL。
-
base:用于指定数字的基数,它的取值范围是2到36之间,或者是特殊值0。Base的值决定了字符串转换为整数时允许的字符范围。例如,base为2时只接受’0’和’1’;base为8时接受’0’到’7’;base为16时接受’0’到’9’以及’a’到’f’(表示十六进制,不区分大小写),其中’a’到’z’代表10到35。
-
当base设置为0时,字符串中的"0x"前缀表示以16为基数,而"0"前缀表示以8为基数
-
当base设置为16时,字符串也可以使用"0x"前缀
-
-
返回值:分别返回转换之后得到的 long int 类型数据以及 long long int 类型数据
-
-
字符串转浮点数型数据
-
atof 函数
-
将字符串转换为一个 double 类型的浮点数据
-
#include <stdlib.h>
double atof(const char *nptr);-
nptr:需要进行转换的字符串
-
返回值:返回转换得到的 double 类型数据
-
-
-
trtod、strtof、strtold 函数
-
可分别将字符串转换为 float 类型数据、double 类型数据、long double 类型数据
-
#include <stdlib.h>
double strtod(const char *nptr, char **endptr);
float strtof(const char *nptr, char **endptr);
long double strtold(const char *nptr, char **endptr);-
nptr:需要进行转换的目标字符串
-
endptr:是一个指向char**类型的指针,用于在strtol()或strtoll()函数中指示字符串中第一个无效字符的位置。如果endptr不是NULL,函数会将无效字符的地址存储在endptr中。如果没有找到数字,函数会将原始的nptr值存储在endptr中并返回0。如果不需要这个信息,可以将endptr设置为NULL。
-
返回值:分别返回转换之后得到的 long int 类型数据以及 long long int 类型数据
-
-
数字转字符串
- 使用格式化 IO 相关库函数
6、给应用程序传参
通过外部传参使应用程序更灵活。传统的硬编码方式,如open 打开固定文件路径,导致每次更改功能都需要修改代码并重新编译,非常不便。通过将可变信息如文件路径作为参数传递给应用程序,可以在不修改源码的情况下,通过改变参数来实现不同功能,提高了应用程序的灵活性和便捷性。
int main(int argc, char **argv)
{
/* 代码 */
}
int main(int argc, char *argv[])
{
/* 代码 */
}