字符数组
char word[] = {‘H’, ‘e’, ‘l’, ‘l’, ‘o’,‘!’};
字符串
char word[] = {‘H’, ‘e’, ‘l’, ‘l’, ‘o’,‘!’,’ \0’};
- 以0(整数0)结尾的⼀串字符
- 0或’\0’是⼀样的,但是和’0’不同
- 0标志字符串的结束,但它不是字符串的⼀部分
- 计算字符串⻓度的时候不包含这个0
- 字符串以数组的形式存在,以数组或指针的形式访问
- 更多的是以指针的形式
- string.h ⾥有很多处理字符串的函数
字符串变量
char *str = “Hello”;
char word[] = “Hello”;
char line[10] = “Hello”;
“Hello”
″Hello″ 会被编译器变成⼀个字符数组放在某处,这个数组的⻓度是6,结尾还有表⽰结束的0
两个相邻的字符串常量会被⾃动连接起来
⾏末的\表⽰下⼀⾏还是这个字符串常量
C语⾔的字符串是以字符数组的形态存在的
- 不能⽤运算符对字符串做运算
- 通过数组的⽅式可以遍历字符串
唯⼀特殊的地⽅是字符串字⾯量可以⽤来初始化字符数组
以及标准库提供了⼀系列字符串函数
char* s = "Hello, world!";
- s 是⼀个指针,初始化为指向⼀个字符串常量
- 由于这个常量所在的地⽅,所以实际上s是 const char* s ,但是由于历史的原因,编译器接受不带 const的写法
- 但是试图对s所指的字符串做写⼊会导致严重的后果
- 如果需要修改字符串,应该⽤数组: char s[] = “Hello, world!”;
什么时候用指针,什么时候用数组
char * str = “Hello”;
char word[] = “Hello”; - 数组:这个字符串在这⾥
- 作为本地变量空间⾃动被回收
- 指针:这个字符串不知道在哪⾥
- 处理参数
- 动态分配空间
如果要构造⼀个字符串—>数组
如果要处理⼀个字符串—>指针
char*是字符串
字符串可以表达为char的形式
char不⼀定是字符串
本意是指向字符的指针,可能指向的是字符的数组(就像int* ⼀样)
只有它所指的字符数组有结尾的0,才能说它所指的是字符串
字符串赋值?
- char * t = “title”;
- char * s;
- s = t;
- 并没有产⽣新的字符串,只是让指针s指向了t所指的字符串,对s的任何操作就是对t做的
字符串输⼊输出
char string[8];
scanf(“%s”, string);
printf(“%s”, string);
scanf读⼊⼀个单词(到空格、tab或回⻋为⽌)
scanf是不安全的,因为不知道要读⼊的内容的⻓度
安全的输⼊
char string[8];
scanf(“%7s”, string);
在%和s之间的数字表⽰最多允许读⼊的字符的数量,这个数字应该⽐数组的⼤⼩⼩⼀
下⼀次scanf从哪⾥开始?
下一次scanf从上一个第八个开始
常⻅错误
- char * string;
- scanf(“%s”, string);
- 以为char* 是字符串类型,定义了⼀个字符串类型的变量string就可以直接使⽤了
- 由于没有对string初始化为0,所以不⼀定每次运⾏都出错
空字符串
char buffer[100]=””;
- 由于没有对string初始化为0,所以不⼀定每次运⾏都出错
这是⼀个空的字符串,buffer[0] == ‘\0’
char buffer[] = “”;
这个数组的⻓度只有1!
• char **a
• a是⼀个指针,指向另⼀个指针,那个指针指向⼀个字符(串)
• char a[][]
• a是⼀个⼆维数组,第⼆个维度的⼤⼩不知道,不能编译
• char a[][10]
• a是⼀个⼆维数组,a[x]是⼀个char[10]
• char *a[]
• a是⼀个⼀维数组,a[x]是⼀个char*
程序参数
- int main(int argc, char const * argv[])
- argv[0]是命令本⾝
- 当使⽤Unix的符号链接时,反映符号链接的名字
putchar
- int putchar(int c);
- 向标准输出写⼀个字符
- 返回写了⼏个字符,EOF(-1)表⽰写失败
getchar
- int getchar(void);
- 从标准输⼊读⼊⼀个字符
- 返回类型是int是为了返回EOF(-1)
- Windows—>Ctrl-Z
- Unix—>Ctrl-D
strlen
size_t strlen(const char * s);
返回s的字符串⻓度(不包括结尾的0)
char line[]="Hello"
printf("strlen=%lu\n",strlen(line));
printf("sizeof=%lu\n",sizeof(line));
输出结果为:
strlen=5
sizeof=6
strcmp —compare
- int strcmp(const char * s1, const char * s2);
- ⽐较两个字符串,返回:
- 0:s1== s2
0:s1>s2
- <0:s1< s2
int mycmp(const char *s1,const char *s2)
{
int idx = 0;
while (s1[idx] == s2[idx] && s1[idx] != 0)
{
idx++;
}return s1[idx] - s2[idx];
}
等同于
int mycmp(const char *s1,const char *s2)
{
while (*s1==*s2&&*s1!='\0')
{
s1++; s2++;
}
return *s1 - *s2;
}
strcpy —copy
char * strcpy(char *restrict dst, const char *restrict src);
- 把src的字符串拷⻉到dst
- restrict表明src和dst不重叠(C99)
- 返回dst
- 为了能链起代码来
复制字符串
- 为了能链起代码来
char *dst = (char*)malloc(strlen(src)+1); //+1包括结尾最后的\0
strcpy(dst, src);
用函数等价
数组版本
char* mycpy(char*dst,const char* src)
{
int idx = 0;
while(src[idx]){
dst[idx]=src[idx];
idx++;
}
dst[idx]='\0';
return dst;
}
指针版本
char* mycpy(char*dst,const char* src)
{
char *ret=dst;
while( *dst++ = *src++ )
;
*dst='\0';
return ret;
}
strcat
char * strcat(char *restrict s1, const char *restrict s2);
- 把s2拷⻉到s1的后⾯,接成⼀个⻓的字符串
- 返回s1
- s1必须具有⾜够的空间
char *mycat(char cat1[],const char cat2[]) //声明并实现我的猫字符指针函数。
{ int i = 0;
int j = strlen(cat1); //猫1字符数组的最后一位下标j while(i != strlen(cat2)){ //当猫2的下标为最后一位\0时跳出循环 cat1[j] = cat2[i]; //猫1最后一位为猫二的第一位字符
i++;
j++;
}
cat1[j] = '\0'; //猫1字符数组最后一位为0
return cat1; //让我的猫字符指针指向猫1字符数组
}
安全问题
strcpy和strcat都可能出现安全问题:如果那个dst或者要连接的地方没有足够的空间,不知道是否越界
安全版本
char * strncpy(char *restrict dst, const char *restrict src, size_t n);
char * strncat(char *restrict s1, const char *restrict s2, size_t n);
int strncmp(const char *s1, const char *s2, size_t n);
在名字中间和参数表中多了一个n
n的意思是说你能拷过去多少个字符;多了的部分直接掐掉,不会越界。
对于cmp来说是比较前n个的大小
strchr
在参数 str 所指向的字符串中搜索第一次出现字符 c(一个无符号字符)的位置。
#include#includeint main ()
{
const char str[] = "http://www.nowcoder.com";
const char ch = '.';
char *ret;
ret = strchr(str, ch);
printf("|%c| 之后的字符串是 - |%s|\n", ch, ret);
return(0);
}
运行结果为
|.| 之后的字符串是 - |.nowcoder.com|
strrchr
在参数 str 所指向的字符串中搜索最后一次出现字符 c(一个无符号字符)的位置。
#include#includeint main ()
{
int len;
const char str[] = "https://www.nowcoder.com";
const char ch = '.';
char *ret;
ret = strrchr(str, ch);
printf("|%c| 之后的字符串是 - |%s|\n", ch, ret);
return(0);
}
运行结果为
|.| 之后的字符串是 - |.com|
strstr()
在字符串 haystack 中查找第一次出现字符串 needle 的位置,不包含终止符 ‘\0’。
下面是 strstr() 函数的声明。char
*strstr(const
char
*haystack,
const
char
*needle)
#include
#include
int
main()
{
const
char
haystack[20] = "NOWCODERABCD";
constchar
needle[10] = “CODER”;
char *ret;
ret = strstr(haystack, needle);
printf("子字符串是: %s\n"
, ret);return(0);
}`
输出结果为
子字符串是: CODERABCD
memcpy
和strcpy类似,只不过它是拷贝字节
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
网页标题:C语言字符串+字符串函数-创新互联
文章分享:http://cqwzjz.cn/article/djceip.html