字符串
一、字符
常用字符
‘\0’ ASCII值是 0
‘0’ ASCII值是 48
‘A’ ASCII值是 65
‘a’ ASCII值是 97
注意事项:
当先输入数值型数据(整数形、浮点型),再输入字符型数据时,前一次的输入会残留一个’\n’或空格,影响字符型数据的输入,有以下三种解决方法。
方法1:增加一个空白的字符输入语句。
scanf("%*c");
getchar();
方法2:在%c的前面增加一个空格
scanf(" %c");
方法3:修改输入缓冲区
stdin->_IO_read_ptr = stdin->_IO_read_end;
函数名 | 函数功能 |
---|---|
isalnum() | 当字母或数字字符时, 返回真值 |
isalpha() | 当字母字符时, 返回真值 |
iscntrl() | 当控制字符时, 返回真值 |
isdigit() | 当数字字符时, 返回真值 |
isgraph() | 当非空格可打印字符时, 返回真值 |
islower() | 当小写字母字符时, 返回真值 |
isprint() | 当可打印字符时, 返回真值 |
ispunct() | 当标点字符时, 返回真值 |
isspace() | 当空格字符时, 返回真值 |
isupper() | 当大写字母字符时, 返回真值 |
isxdigit() | 当十六进制字符时, 返回真值 |
二、字符串
由字符类型组成的串型结构,它的结束标志是’\0’,一般使用char类型的数组存储。
-
字符串字面值
1、“由双引号包括着的若干个字符”
2、它是以常量字符数组的形式存在,末尾隐藏着一个’\0’。
3、它们会被存储在text内存段,一旦强行修改就会出现段错误。
4、使用指针指向字符串字面值时,一定要用const加以保护,防止出现段错误。
5、编译器会优化它的存储,相同的字符串字面值,只会存储一份在text内存段中。
6、最常用的是用它给字符数组初始化,char arr[] = “hello” 编译器会自动拷贝字符串到数组的内存中**(包括’\0’)**,完成初始化就有了两份字符串存储在内存中,一份存储在stack、data,另一份还存储在text。
**注意:**使用字符串字面值给字符数组赋值,只能在定义字符数组时使用,这是编译器帮忙完成拷贝的,在完成字符数组的定义后,只能使用strcpy函数对字符串进行赋值。
-
字符串的输入输出
//输入 scanf("%s",存储字符串的首地址); 缺点:不能输入带空格的字符串 char *gets(char *s); 缺点:从终端读取数据,直到遇到\n,它不关心存储字符串的空间有多大,所以可能产生段错误、脏数据,官方不建议使用该函数。 /*通过查看手册可以看到官方建议 Never use gets(). Because it is impossible to tell without knowing the data in advance how many characters gets() will read, and because gets() will continue to store characters past the end of the buffer, it is extremely dangerous to use. It has been used to break computer security. Use fgets() instead. */ char *fgets(char *s, int size, FILE *stream); 功能:从指定的文件中读取不超过size-1个字符(它会为'\0'预留位置)。 stream:数据的来源,(stdin) 缺点1:如果输入的字符不足size-1个,它会连'\n'一起读入。 缺点2:如果输入的字符超过size-1个,fgets只会从输入缓冲区中读取size个字符,剩余的数据会残留输入缓冲区中影响后续数据的输入。 //输出 printf("%s",字符串的首地址); puts(字符串的首地址); // 输出完字符串后会再输出一个\n
三、常用函数及实现
size_t strlen(const char *s);
功能:计算字符串的长度,不包括'\0'
char *strcpy(char *dest, const char *src);
功能:把字符串src拷贝到dest处
int strcmp(const char *s1, const char *s2);
功能:按字典序比较两个字符串
s1 > s2 返回正数
s1 < s2 返回负数
s1 == s2 返回0
char *strcat(char *dest, const char *src);
功能:把src字符串追加到dest的末尾
//=====实现=====
#include<stdio.h>
#include<assert.h>
size_t my_strlen(const char* s)
{
//为假执行
assert(NULL!=s);
const char* tmp=s;
while(*(tmp++));
return tmp-s-1;
}
char* my_strcpy(char* dest,const char* src)
{
assert(NULL!=dest&&NULL!=src);
char* tmp=dest;
while(*tmp++ = *src++);
return dest;
}
int my_strcmp(const char* s1,const char* s2)
{
assert(NULL!=s1||NULL!=s2);
//防止全部相等,最后‘\0’越界
while(*s1 == *s2&& *s1)
s1++,s2++;
if(*s1>*s2)
return 1;
if(*s1<*s2)
return -1;
return 0;
/*
return *s1-*s2;
*/
}
char* my_strcat(char* dest,const char* src)
{
assert(NULL!=dest&&NULL!=src);
char* tmp=dest;
while(*tmp)
tmp++;
while(*tmp++ = *src++);
return dest;
}