VS2019项目出现"const char *" 类型的实参与
“char*” 类型的形参不兼容错误的解决方法解决方案一 在VS2019中依次点击项目->属性->C/C+±>语言->符合模式,将原来的“是”改为“否”即可。 解决方案二 在声明变量 char* 时改成 const char *即可
https://blog.csdn.net/edward_zcl/article/details/89451078 https://blog.csdn.net/YfBong/article/details/90277418
char* s != char s[x] 虽然都能表示字符串 但是两者一个能修改字符串 一个是指定一个字符段且不能改
字符串 即末尾为\0
- 字符数组!=字符串 ,因为不能用字符串的方式来计算
- 字符串 => char word [] = {'H','e','l','l','o','!','\0'}; '\0' == 0 使得字符数组变成C语言的字符串
字符数组 => char word [] ={{'H','e','l','l','o','!'}; - 字符串以'\0' (整数0 )结尾的一串字符
0 或'\0' 是一样的 【有些时候强调的是'\0是一个字节' 而0 是四个字节】,但是和'0'不同 - 0标志字符串的结束,但它不是字符串的一部分
计算字符串长度的时候不包含这个0 - 字符串以数组的形式存在,以数组或指针的形式访问
更多的是以指针的形式 - string.h 有很多处理字符串的函数
字符串变量
- char * str = "hello";
- char word[] = "hello";
- char line[10] = "hello"; 占据六个位置 6个字节 包括 \0(编译器自动生成\0加在字符串最后面 再赋值到line中)
字符串常量
"hello"
"hello" 会被编译器变成一个字符数组放在某处,这个数组的长度是6,结尾还有表示结束的0
两个相邻的字符串常量会被自动连接起来
#include<stdio.h> int main(void) { printf("考研" //自动连接 "加油\n"); printf("考研 \ 加油");//需置顶 return 0; } //考研加油 //考研加油
C语言字符串
C语言的字符串是以字符数组的形态存在的
不能用运算符对字符串做运算 包括:字符串+字符串 直接即可:字符串字符串
通过数组的方式可以遍历字符串
唯一特殊的地方是字符串面量可以用来初始化字符数组
以及标准库提供一系列字符串函数
char* 字符串是一个常数
s 是一个指针,初始化为指向一个字符串常量 i为变量 s2也是字符串
由于这个常量所在的地方,所以实际上s是const char* s 但是由于历史的原因 ,编译器接受不带 const 的写法
但是试图对s所指的字符串做写入会导致严重的后果
如果需要修改字符串,应该用数组: char s3[] = "HELLO";
#include<stdio.h> int main(void) { char* s = "Hello world"; //"hello world" 代码段 放在很小地址那 //--> s[0] = 'B'; //ERROR 保护机制 char* s2 = "Hello world"; //需要区别于 != char []s2 数组可以修改 printf("%p\n", s); printf("%p", s2); //得 s == s2 是同一个 return 0; 32位架构 //006FFA60 有差距 //00917BD8 //00917BD8 64位架构 // 0x7ffe6adbecf0 有差距 // 0x414420 小的很 代码段 且有保护机制 // 0x414420 }
指针or 数组
- 数组:这个字符串在这里
作为本地变量空间自动被回收 - 指针:这个字符串不知道在哪里
处理参数
动态分配空间
如果要构造一个字符串--->数组
如果要处理一个字符串--->指针
char* 是字符串吗?不一定 char* + \0 是字符串
- 字符串可以表达为char * 的形式
- char* 不一定是字符串
本意是指向字符的指针,可能指向的是字符的数组(int * 一样 也可能是一个int数组)
只有他指向的字符数组有结尾的0 才可以说他指的是字符串
字符串赋值
char* t = "title";
char *s;
s = t;
并没有产生新的字符串,只是让指针s指向了t所指的字符串,对s的任何操作就是对t做的
重新指向而非更改!!!
字符串的输入输出
代码
char string[8]; //超过八个字符 (只能接受七个 + \0) scanf("%s",string); //hello word 中间的空格会被当成分割两个字符串 读到空格就停了 【不安全】 printf("%s",string); scanf读入一个单词 (到空格、tab或回车为止) scanf是不安全的,因为不知道要读入什么内容的长度 ??? scanf("%7s",word); //最多读七个字符 大于七就不要了 并留给下一个
常见错误
- char * string
- scanf("%s",string);
- 以为char* 是字符串类型,定义了一个字符串类型的变量string 就可以直接使用了
- 由于没有对string初始化为0,所以不一定每次运行都出错
空字符串
- char buffer[100] ="" 这是一个空的字符串 ,buffer[0] =='\0'
- char buffer[] = ""; 这个数组的长度只有1
代码输入12345678 12345678超过承载 有什么问题
代码 情况一是会报错 【这种是先定义在低地址 后定义在高地址】
而情况二##12345678## 【先变量在高地址 后定义在地址 可以通过取地址来进行验证】导致第一个word[0]='\0'输出为空#include<stdio.h> int main(void){ char word[8]; char word2[8]; scanf("%s",word); //12345678 scanf("%s",word2); //12345678 printf("%s##%s",word,word2); //##12345678 word没有输出 return 0; }
- 为避免输入越界 可以采用scanf("%7s",&arr) 仅读小于7个 但是多余的字符会留到下一个
#include<stdio.h> int main(void) { char c1[8]; char c2[8]; //12345678 12345678 scanf("%7s", &c1); scanf("%7s", &c2); printf("%s\n",c1); printf("%s\n",c2); return 0; //1234567 //8 }
字符串数组用来表示很多个字符串
char **a:a是一个指针,指向另外一个指针,那个指针指向一个字符(串)
) "图片标题")char a[][10]
) "图片标题")char *a[10] 指针数组, 10个一维的,每个数组中都存放一个char *的东西 []结合优先级高于 *
#include<stdio.h> int main(void){ //char arr1[] = {"123","456","789","9123456789","131499",};//ERROR char arr2[][10] = {"123","456","789","123456789123","1131499",};//9123456789过长 导致\0写到下一块区域 printf("%s\n",arr2[3]); printf("%s\n",arr2[4]); char *arr3[] = {"123","456","789","9123456789","131499",}; return 0; } //12345678911131499 //1131499
程序参数
- int main(int args , char const* argv[]) 字符串数组
- argv[0] 是命令本身【在Unix 运行同一个代码可以用符号连接】,当使用Unix的符号连接时,反映符号链接的名字
- 符号链接
#include<stdio.h> int main(int argc, char const*argv[]){ int i ; for(i=0 ; i < argc ; i++){ printf("%d:%s\n",i , argv[i]); } return 0; }
字符串函数
putchar
- int putchar(int c); int整数能够接收的是一个字符
- 向标准输出写一个字符 char -> int return int ;
- 返回写了几个字符, EOF(-1)表示写失败
getchar 会等用户输入东西取出来
int getchar(void);
从标准输入读入一个字符
返回类型是int是为了返回EOF(-1)
Windows -> ctrl - z
Unix ——> ctrl - D#include<stdio.h> int main(int argc, char const*argv[]){ int ch; while((ch = getchar())!= EOF){ putchar(ch); printf("-------\n"); //one by one } printf("EOF\n"); return 0; }
键盘输入- - - 缓冲区 --- 回车 --- 显示
字符串函数
string.h
strlen
size_t strlen(constr char*s); constr 保证不修改s字符串 而char s[] 变成是一个一个字符
返回s的字符串长度(不包括结尾的0)
int是有符号整型,包括小于0的整数,size-t是无符号整型,只有0到max的整数。#include<stdio.h> #include<string.h> size_t mystrlen(const chara){ int idx = 0 ; while(a[idx] != '\0')idx++; return idx; } int main(int argc, char constargv[]){ char a[] = "Hello , world"; printf("strlen(a)= %lu\n",strlen(a)); printf("mystrlen(a)= %lu\n",mystrlen(a)); printf("sizeo***",sizeof(a)); return 0; }
strcmp 哪个位不相等 相减返回 acdadf < b
int strcmp(const char *s1 , const char *s2); 安全版本 strncmp 末尾加一个参数 表示比较前几个
比较两个字符串,返回- 0:s1 == s2
- 1: s1>s2
- -1: s1<s2
#include<stdio.h> #include<string.h> int main(int argc, char const*argv[]){ char *a = "abc"; //指针还可以进行==比较 char *b = "abc"; printf("%d\n",strcmp(a,b)); printf("%d\n",a==b); char c[] = "efg"; char d[] = "efg"; printf("%d\n",strcmp(c,d)); printf("%d\n",c==d);// 数组的比较永远是false 不可以用==进行比较 char e[] = "efg"; char f[] = "abc"; printf("%d\n",strcmp(e,f)); printf("%d\n",e==f); return 0; }
4 = "efg" 和 "abc"的e a 差值 那个大那个小 高位重要性大于地位 所以高位先出现不同 直接return
strcpy 但存在安全问题---> 安全版本 strncpy 在末尾加一个int参数表示拷贝多少个
- char * strcpy(char * restrict dst 目的 , const char* restrict src 材料);
- 把src的字符串拷贝到dst
- restrict 表明 src 和 dst 不重叠(C99) [][][1][2] --->[1][2][][] 这就是重叠 因为底层分段拷贝 节省性能 重叠无法实现该效果
- 返回dst
- 为了能链起代码来
#include<stdio.h> #include<string.h> int main(int argc, char const*argv[]){ char *a = "bcdadf"; char * dst = (char*)malloc(strlen(a)*sizeof(char)+1) ;//'/0' strcpy(dst,a); printf("%s",dst);//bcdadf return 0; }
strcat 连接 字符串(s1 , s2) 但存在安全问题---> 安全版本 strncat 在末尾加一个int参数表示末尾添加多少个
把s2拷贝到s1后面 也就是s1的\0替换成s2[0]
返回s1 且s1必须要有足够的空间
字符串搜索函数
返回NULL是没有找到 空指针
- char* strchr(const char * s , int c)
- char * strrchr(const char * s , int c)
- 代码 找到同个字母的第二个开始的字符串
#include<stdio.h> #include<string.h> #include<stdlib.h> int main(int argc, char const*argv[]){ char *s = "hello";//char s[] = "hello"; char * p = strchr(s,'l'); char * p1 = strchr(p+1,'l'); //不知道p之后多大 char * p2 = (char* )malloc(strlen(p1)+1); strcpy(p2,p1); printf("%s\n",p); printf("%s\n",p1); printf("%s\n",p2); free(p2); return 0; } //llo //lo //lo
- 找到某字母前的一段
#include<stdio.h> #include<string.h> #include<stdlib.h> int main(int argc, char const*argv[]){ char s[] = "hello";//char *s = "hello"; char * p = strchr(s,'l'); *p = '\0'; //字符串要用数组存储 char * p1 = (char* )malloc(strlen(s)+1); strcpy(p1,s); printf("%d\n",strlen(p1)); *p = 'l'; printf("%s\n",s); printf("%s\n",p1); free(p1); return 0; } //hello //he
- char* strstr(字符串,字符串) 在字符串中找到目标字符串
- char* strcasestr(字符串,字符串) 在字符串中找到目标字符串 且忽略大小写