女孩子学做网站有前途吗,网站设计宽屏,html网站登陆页面模板,网站建设开源节流在编程的过程中#xff0c;我们要经常处理字符和字符串#xff0c;为了方便操作字符和字符串#xff0c;c语言标准库中提供的一系列库函数#xff0c;接下来我们就开始学习与认识他们
1.字符分类函数
c语言中有一系列的函数是专门做字符分类的#xff0c;也就是一个字符…在编程的过程中我们要经常处理字符和字符串为了方便操作字符和字符串c语言标准库中提供的一系列库函数接下来我们就开始学习与认识他们
1.字符分类函数
c语言中有一系列的函数是专门做字符分类的也就是一个字符是属于什么类型的字符的
这些函数的使用需要包含一个头文件ctype.h 用islower举例
格式int islower (int c)
为什么后面的是int c--用整型接受的因为传过来的是字符或者对应的ASCII值
那么我们就用整型接受
返回值也是int
如果这个字符是小写字母的话那么返回值就是一个非0数字
如果这个字符是一个大写字符的话那么返回值就是0
总之如果括号内的不是小写字母那么这个函数就会返回一个0
是小写字母就返回一个非0数字
int main()
{int ret1 islower(b);//2printf(%d\n, ret1);int ret2 islower(A);//0printf(%d\n, ret2);int ret3 islower(0);//字符0不是字母printf(%d\n, ret3);return 0;
}int main()
{int ret1 isdigit(A);//不是数字字符就返回0printf(%d\n, ret1);int ret2 isxdigit(A);//A是16进制的字符--返回的就是非0值printf(%d\n, ret2);return 0;
}//写一个代码将字符串中的小写字母转换成大写字母其他字符不变
int main()
{char arr[] I am a student;//末尾隐藏\0//需要遍历字符串--通过下标进行访问int i 0;while (arr[i] ! \0)//不等于\0就一直遍历数组直到遇到\0就停止遍历数组{//判断这个数组内的字符是不是小写字母if (islower(arr[i]))//如果不是小写字母返回值就是0是小写字母返回值就是非0数字//这个函数是用来判断输入的字符是不是小写字母{//小写字母转大写字母的方法//小写字母的ASCII-32对应放入大写字母ASCIIarr[i] arr[i] - 32;}i;//没有遇到\0就i}printf(%s, arr);return 0;
}//小写字母转大写字母出了这个toupper函数还可以直接通过小写字母的ASCII-32就可以进行转换了//那么我们对上面的问题进行改造一下
int main()
{char arr[] I am a student;//末尾隐藏\0//需要遍历字符串--通过下标进行访问int i 0;while (arr[i] ! \0)//不等于\0就一直遍历数组直到遇到\0就停止遍历数组{//判断这个数组内的字符是不是小写字母if (islower(arr[i]))//如果不是小写字母返回值就是0是小写字母返回值就是非0数字//这个函数是用来判断输入的字符是不是小写字母{//小写字母转大写字母的方法arr[i] toupper(arr[i]);//小写字母通过toupper这个函数转换为大写字母了}i;//没有遇到\0就i}printf(%s, arr);return 0;
}
//对于这个循环还有一种判断是不是小写字母的方法
//if(arr[i]aarr[i]z)
//在这个区间内的就都是小写字母了这些字符分类函数主要是进行判断
2.字符转换函数
c语言提供两个字符转换函数
int tolower(int c);//将参数传进去的大写字母转小写
int toupper(int c);//将参数传进去的小写字母转大写
//int main()
//{
// char ch toupper(a);
// printf(%c\n, ch);//打印出来的就是A大写的A
//
// //如果传进来的大写字母那么输出的还是大写字母不做判断
// ch tolower(A);
// printf(%c\n, ch);//将大写字母转换为小写字母
//
//
// return 0;
//}
//小写字母转大写字母出了这个toupper函数还可以直接通过小写字母的ASCII-32就可以进行转换了//那么我们对上面的问题进行改造一下
int main()
{char arr[] I am a student;//末尾隐藏\0//需要遍历字符串--通过下标进行访问int i 0;while (arr[i] ! \0)//不等于\0就一直遍历数组直到遇到\0就停止遍历数组{//判断这个数组内的字符是不是小写字母if (islower(arr[i]))//如果不是小写字母返回值就是0是小写字母返回值就是非0数字//这个函数是用来判断输入的字符是不是小写字母{//小写字母转大写字母的方法arr[i] toupper(arr[i]);//小写字母通过toupper这个函数转换为大写字母了}i;//没有遇到\0就i}printf(%s, arr);return 0;
}
//对于这个循环还有一种判断是不是小写字母的方法
//if(arr[i]aarr[i]z)
//在这个区间内的就都是小写字母了3.strlen的使用和模拟实现
strlen格式size_t strlen(const char * str);
统计的是\0之前的个数
strlen的返回值是size_t类型的
//
//int main()
//{
// char arr1[] abcdef;
// size_t lenstrlen(arr1);//输出的数据是6
// printf(%zd\n, len);
//
//
// char arr2[] { a,b,c,d,e,f };//这里面是没有\0的
// size_t len1 strlen(arr2);
// printf(%zd\n, len1);//输出数据是17
// return 0;
//}
//注意函数的返回值是sizeof_t是无符号的int main()
{if (strlen(abc) - strlen(abcdef) 0)
//另一种写法if(strlen(abc)strlen(abcdef)){// size_t类型 size_t类型printf(\n);}else{printf(\n);}return 0;
}
//输出的结果是,为什么呢
//当两个无符号整型进行计算的时候算出来的结果还是无符号整型的结果
//如果想得到-3的话那么我们需要将strlen(abc)和strlen(abcdef)强制类型转换为int 类型的数据strlen的模拟实现的三种方法
1.计数器的方法
2.指针~指针
size_t my_strlen(const char*str)//返回类型是sizeof_t因为传过来的是字符串首元素的地址那么我们用一个字符指针进行接收
{//前面加上const防止被修改//利用传过来的首元素的地址我们遍历数组统计\0之前的元素个数//只要不是\0就统计一个数字int count 0;//因为str是指针变量为了防止str是空指针我们要进行断言一下assert(str ! NULL);//如果str为空指针就报错while (*str ! \0){count;str;//使指针向后走一步}return count;}
int main()
{char arr[] abcdef;size_t len my_strlen(arr);//自己创建一个函数来实现strlen函数//传过去一个数组名字符串首元素的地址printf(%zd\n, len);return 0;
}//第二种方法指针-指针
//两个指针相减就能得到两个指针之间的元素个数了
size_t my_strlen(const char* str)
{char* start str;assert(str ! NULL);while (*str ! \0){str;//走到\0前面就停止了那么到最后str的值是最后一个元素的地址}return str - start;//因为一开始将第一个元素的地址赋值给start了那么现在指针相减得到的就是两个指针之间的元素的个数了}int main()
{char arr[] abcdef;size_t len my_strlen(arr);//自己创建一个函数来实现strlen函数//传过去一个数组名字符串首元素的地址printf(%zd\n, len);return 0;
}//这种写法可以不创建临时变量//使用递归来实现
size_t my_strlen(const char* str)
{if (*str ! \0){ return 1 my_strlen(str 1);}else{return 0;}
}int main()
{char arr[] abcdef;size_t len my_strlen(arr);//自己创建一个函数来实现strlen函数//传过去一个数组名字符串首元素的地址printf(%zd\n, len);return 0;
}4.strcpy的使用和模拟实现
功能拷贝字符串
strcpy---cpoy string
strcpy在拷贝的过程中会将arr1里面的内容包括\0拷贝到arr2里面去
int main()
{char arr1[] hello world;char arr2[20] { 0 };//现在想把arr1里面的hello world放到arr2里面去//我们可以用strcpy来实现strcpy(arr2, arr1);printf(%s\n, arr2);return 0;
}注意注意
被拷贝的字符串一定要包含\0保证strcpy遇到\0就能停止拷贝
1.源头的字符串中必须包含\0没有\0strcpy是不能结束的
2.目标空间必须足够大以确保能存放原字符串
3.目标空间必须是可以修改的
int main()
{char arr1[] hello world;char* p xxxxxxxxxxxxxx;//常量字符串--不能修改strcpy(p, arr1);//会报错的return 0;
}//模拟实现拷贝
char*my_strcpy(char*dest,const char*src)//传过来的是首元素的地址,返回值是目标空间的起始地址所以就是char*
{//*dest指向的是arr2第// 一个元素*src指向的是arr1第一个元素//保证这两个指针不为空指针/*assert(src ! NULL);assert(dest ! NULL);*///另一种写法assert(dest src);//如果dest为空指针那么括号内就为0就是假的就会报错char* ret dest;//将dest存起来while (*src ! \0){*dest*src;//进行加加操作换下一个字符和下一个位置进行交换src;dest;}//当这个循环结束的时候\0还没有被拷贝进去//最后的时候src已经成为\0了那么现在再次赋值就能将\0拷贝进去了*dest * src;//这里处理的就是\0return ret;//直接返回目标空间的起始地址}
int main()
{char arr1[] abcdef;//末尾隐藏\0char arr2[20] { 0 };//1.直接打印arr2my_strcpy(arr2, arr1);printf(%s\n, arr2);//2.接收返回值char* p my_strcpy(arr2, arr1);printf(%s\n, p);//直接将返回值放到打印里面也可以printf(%s\n, my_strcpy(arr2, arr1));return 0;
}//这个函数返回的是char*为的是实现链式访问//strcpy函数返回的是字符串拷贝成功过后目标空间的起始地址
//返回值就是arr2的首元素的地址//总结
//将arr1拷贝到arr2后我们可以通过三种方法直接打印arr2
//一种就是直接打印arr2
//还有一种就是根据这个拷贝函数的返回值进行打印
//返回值是一个地址在函数的一开始我们就将目标函数赋值给另一个临时指针那么这个临时指针就指向了arr2
//在拷贝过后我们直接将这个临时指针返回所以在函数的开头我们用char*
//在返回了临时指针后我们在主函数就用再创建一个临时指针变量进行返回值的接受
//因为这个临时指针变量指向的是arr2的其实元素那么我们就可以用这个临时指针变量直接打印arr2
//有了字符串起始元素的地址我们就能打印这个字符串了//对函数部分进行改进
//思考能不能将拷贝\0和前面的字符串放在一起呢char*my_strcpy(char*dest,const char*src)
{assert(dest src);char* ret dest;while (*dest *src)//因为这里是后置所以先带进去数据进行解引用再进行{//arr1里面的字符通过*dest *src这个代码一个个拷贝到arr2里面去了//在最后*src是\0拷贝过去了然后因为while循环里面是\0,所以循环停止了// 但是\0拷贝到dest里面了 ;}//这个循环拷贝过去之后判断表达式的值//因为是后置所以延后产生return ret;}int main()
{char arr1[] abcdef;char arr2[20] { 0 };my_strcpy(arr2, arr1);printf(%s\n, arr2);char* p my_strcpy(arr2, arr1);printf(%s\n, p);printf(%s\n, my_strcpy(arr2, arr1));return 0;
}5.strcat的使用和模拟实现
原字符串必须有\0结尾
目标字符串也得有\0,否则没办法知道从哪里开始
目标空间必须足够大能容纳下字符串的内容
目标空间是可以进行修改的而不是常量不能进行修改
int main()
{char arr1[20] hello ;char arr2[] world;//如何将arr2里面的字符串追加在arr1后面呢strcat(arr1, arr2);//字符串追加printf(%s\n, arr1);return 0;
}//这个函数是如何实现追加呢
//先找到目标函数的末尾\0的位置
//再将原字符串拷贝过来//要求目标字符串末尾有\0,因为后面要将原字符串拷贝过去所以原字符串也要有\0//要返回目标空间的起始地址
//目标空间是可修改的但是源头需要进行限制不能被修改
char* my_strcat(char* dest,const char* src)//返回类型为char*类型的
//dest指向的是arr1的首元素的地址
//src指向的是arr2首元素的地址
{char* ret dest;//将起始位置存起来assert(dest src);//进行断言防止空指针//1.找目标空间的\0while (*dest ! \0){dest;}//while循环找到\0就停下来//2.拷贝----我们在字符串追加的时候我们要将目标字符串末尾的\0覆盖掉while (*dest *src)//这个代码是进行字符串间的拷贝的因为上面已经找到\0了已经停止循环了并且dest指向了arr1末尾的\0{;//写个分号就行了循环得有一个循环语句}return ret;//直接返回arr1的起始地址
}
int main()
{char arr1[20] hello ;char arr2[] world;//如何将arr2里面的字符串追加在arr1后面呢my_strcat(arr1, arr2);//字符串追加printf(%s\n, arr1);return 0;
}//这个函数是如何实现追加呢
//先找到目标函数的末尾\0的位置
//再将原字符串拷贝过来//要求目标字符串末尾有\0,因为后面要将原字符串拷贝过去所以原字符串也要有\0//总结 我们应该先找到目标字符串末尾\0的位置这样我们才好追加
//切记追加的时候我们要将目标字符串末尾的\0覆盖掉//在这个追加函数我们用了两个循环第一个循环是找到\0第二个循环是将原字符串拷贝到目标字符串的后面去我们是不能对一个数组自己进行追加的
6.strcmp的使用和模拟实现
strcmp是用来比较两个字符串的
返回值是int
用返回值来比较这两个字符串大小
比较的是对应位置上的字符如果对应位置字符相等就比较下一对字符
比较的不是字符串的长度而是对应位置上字符的大小
如果两个字符串相等返回值就是0
如果前面的字符串大于后面的字符串那么就会返回一个大于0的数字
如果是后面的字符串大于前面的字符前面的字符小就返回一个小于 0的数字
int main()
{char arr1[] abcdef;char arr2[] abq;int retstrcmp(arr1, arr2);//printf(%d\n, ret);//输出的结果是-1就说明arr1arr2if (ret 1)//仅仅在vs平台可以写返回值为1其他的平台就不知道返回值是多少了{printf( );}else{printf();}return 0;
}//
//int main()
//{
// char arr1[] abcdef;
// char arr2[] abq;
// int retstrcmp(arr1, arr2);
// //printf(%d\n, ret);//输出的结果是-1就说明arr1arr2
// if (ret 1)//仅仅在vs平台可以写返回值为1其他的平台就不知道返回值是多少了
// {
// printf( );
// }
// else
// {
// printf();
// }
// return 0;
//}//int my_strcmp(const char*str1,const char*str2)//返回值是Int,并且加上const进行限制
//{
// //我们一对一对字符进行比较
// assert(str1 str2);
// while (*str1 *str2)
// {
// if (*str1 \0)//如果str1在上一轮循环到\0之后就说明这两个字符串已经完全相等了
// {
// return 0;//两个字符串完全相等
// }
// str1;
// str2;
// }//两个字符相等我们就找下一对字符进行比较
// if (*str1 *str2)
// {
// return 1;
// }
// else//*str1 *str2
// {
// return -1;
// }
//}//另一种写法
int my_strcmp(const char* str1, const char* str2)//返回值是Int,并且加上const进行限制
{//我们一对一对字符进行比较assert(str1 str2);while (*str1 *str2){if (*str1 \0)//如果str1在上一轮循环到\0之后就说明这两个字符串已经完全相等了{return 0;//两个字符串完全相等}str1;str2;}//两个字符相等我们就找下一对字符进行比较return (*str1 - *str2);//直接返回他们相减的值}
int main()
{char arr1[] abcdef;char arr2[] abcdef;int retmy_strcmp(arr1, arr2);printf(%d\n, ret);return 0;
}7.strncpy函数的使用
int main()
{char arr1[20] abcdef;char arr2[20] { 0 };strncpy(arr2, arr1, 3);printf(%s, arr2);//打印的结果就是abc,只选择arr1里面的前三位字符进行拷贝return 0;
}int main()
{char arr1[20] abcdef;char arr2[20] xxxxxxxx;strncpy(arr1, arr2, 3);printf(%s, arr1);//输出xxxdefreturn 0;
}拷贝n个字符从原字符串到目标空间
如果原字符串的长度小于n的话则拷贝完原字符串之后在目标的后边追加0直到凑齐n个
8.strncat函数的使用
可以用来给自己追加
在原有的基础上可以选择性的追加n个字符
9.strncmp函数的使用
int main()
{char arr1[20] abcdef;char arr2[20] abc;int retstrncmp(arr1, arr2, 3);//比较三个字符printf(%d, ret);//现在返回值就是0return 0;
}指定几个字符进行比较久进行几个字符比较
总之来说还是比较方便的
10.strstr的使用和模拟实现
在一个字符串里面找子字符串在一个字符串里面找另外一个字符串是否出现
如果要找的字符串出现一次以上那么我们就返回第一次出现的位置
在str1中找str2
如果在str1中没有找到str2的话就会返回一个空指针NULL
int main()
{char arr[] abcdefabcdef;char* p efab;//定义了一个指向字符串常量efab的指针pchar* retstrstr(arr, p);//返回的是e的地址//printf(%s, ret);//打印结果是efabcdefif (ret NULL){printf(不存在\n);}else{printf(%s\n, ret);}return 0;
}char* my_strstr(const char* str1, const char* str2)//我们只是希望在str1中查找str2并不希望将这两个字符串修改了所以要加上const
{assert(str1 str2);//保证两个指针不是空指针const char* s1 NULL;//加上const限制住const char* s2 NULL;const char* cur str1;//一开始指向的是str1的起始位置的//*cur ! \0简化如下当*cur是\0我们就进不去循环了if (*str2 \0)//特殊情况假如str2是空指针那么我们直接返回str1{return str1;}while (*cur)//如果等于\0的话就说明这个字符串已经找完了{//只要*cur不是\0就能一直寻找要找的字符串//分别将起始位置赋值给s1和s2s1 cur;s2 str2; //*s1!\0 *s2! \0简化如下效果还是一样的//就是反正你*s1和*s2是\0这个循环就进不去直接跳出来了while(*s1 *s2 * s1 *s2)//判断两个指针指向位置的字符是否相等{//如果这一对字符相等的情况下我们就往后走判断下一对字符s1;s2;}if (*s2 \0)//说明我们已经在str1里面已经找完了字符串{return cur;//那么我们就直接返回str1中我们记录的cur的位置}cur;//如果*s1*s2的话就cur换下一个字符就跳出这个while循环了//再次循环就s1又被重新赋值了但是s2仍然是被srt2赋值//就是相等与我们在仅仅只是将str1的出发点进行了更换但是str2的还没变//直到能在str1里面找到str2了就是str2语言\0了就说明已经在str1里面找到str2了//如果*s1不为\0,但是*s2已经是\0了那么这个while循环我们就跳出来了}return NULL;//如果cur为\0就是我们已经不可能在str1中找到str2了那我们直接返回空指针}
int main()
{char arr[] abcdefabcdef;char* p bbs;const char* retmy_strstr(arr, p);if (ret NULL)//根据返回值进行判断str1中是否存在str2{printf(不存在\n);}else{printf(%s\n, ret);}return 0;
}
//如果在str1里面提前遇到了\0就说明这个字符串已经找完了还没遇到要找的字符串
//但是str2提前遇到\0的话就说明我们已经找到了要找的字符串了//总结
/*
我们在这个模拟函数中我们最重要的就是创建了一个cur来不断重新定义来找的位置假如在第一次寻找的过程中我们没找到那么cur就进行操作然后s1str2重新赋值
就是我们将要找的字符串的指针重新定义在首元素但是cur一直在往后走
直到s2走到\0就是说明我们已经在str1内找到str2了那么如果找到了的话我们就将cur现在的地址return 回去就是说明我们在str1中cur处可以找到str2了*/我们当前写的strstr函数的实现不是最优的算法
KMP算法---字符串中找字符串---效率更高但是实现更难
11.strtok函数的使用
charstrtok(charstr,const char *sep)
1.sep参数指向一个字符串定义了用作分隔符的字符集合
2.第一个参数指定了一个字符串它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记
3.strtok函数找到str中的下一个标记并将用\0结尾返回一个指向这个标记的指针。注意strtok会改变被操作符的字符串所以被strtok函数切分的字符串一般都是临时拷贝的内容并且可以修改
4.strtok函数的第一个参数不为NULL,函数将找到str中的第一个标记就是第一个分隔符strtok函数将保存他在字符串中的位置
5.strtok函数的第一个参数为NULL函数将在同一个字符串中被保存的位置查找下一个标记。
6.如果字符串中不存在更多的标记则返回NULL指针就是说明这个字符串已经被找完了再没有任何的分隔符了已经尽数转化为\0了
//int main()
//{
// char arr[] abdjskgbvsfkv.net;
// char buf[256] { 0 };
// strcpy(buf, arr);//把arr数据拷贝到buf内//abdjskgb\0vsfkv\0net
// char sep[] .;//char*sep .
// char* retstrtok(buf, sep);
// printf(%s\n, ret);//输出结果就是abdjskgb
//
// char* ret1 strtok(NULL, sep);
// printf(%s\n, ret1);//输出结果就是vsfkv
//
//
// char* ret2 strtok(NULL, sep);
// printf(%s\n, ret2);//输出结果是net
//
//
// return 0;
//}
//strtok的返回值是buf的第一个标记的指针
//当这个函数返回的是一个空指针的时候就说明这个函数已经找完了//上面这种写法必然是错误的我们必须先知道提供的字符串需要切割几段int main()
{char arr[] abdjskgbvsfkv.net;char buf[256] { 0 };strcpy(buf, arr);//把arr数据拷贝到buf内//abdjskgb\0vsfkv\0netchar *sep .;//分割符char* ret NULL;//上个代码的buf只在strtok里面进行一次后面都是空指针//我们利用了for循环的特点初始化只执行一次//就是说只有第一次传的是buf后面传的都是NULLfor (ret strtok(buf, sep); ret ! NULL;retstrtok(NULL,sep)){printf(%s\n, ret);}//只要ret不等于NULL这个循环就一直执行//strtok(buf, sep)的返回值是第一个切割符前面的字符串的地址并将其赋值给ret//每次循环都会运行retstrtok(NULL,sep)将新获得的返回值赋值给ret,然后每次循环就从新位置开始return 0;
}//总结我们定义一个数组arr里面带有分隔符
// 再定义一个空数组将带有分隔符的数组拷贝过来在后面的过程我们都是用这个拷贝的数组
//
// char* ret NULL;定义了一个指向分割后子字符串的指针。
//char *sep .; 定义了分隔符字符串包含 和 .。/*针对这个循环进行更加详细的解释ret strtok(buf, sep)是初始化部分
在循环开始之前strtok被调用使用buf和sep来分割字符串并返回第一个子字符串的指针
这个指针被赋值给ret作为循环的起始点循环条件ret ! NULL 这表示只要strtok返回的指针不是NULL就能继续执行循环体
因为strtok在没有更多子字符串可供分割时会返回NULL所以在没有更多子字符串可供分割时会结束迭代部分ret strtok(NULL, sep)
在每次循环迭代时strtok(NULL, sep)被调用告知strtok继续从上一次的位置继续分割字符串
并返回下一个子字符串的指针这个指针被赋值给ret作为下一次循环的起始点这个循环的条件保证了每次循环迭代都能够正确地从输入字符串中分割出一个子字符串
并且在没有更多子字符串可供分割时结束循环。*///strtok可以把一个字符串切成一段一段的每切一次就将起始地址返回去//每次就直接将分隔符前面的字符串切割下来并将切割符变为\0就是\0后面的字符将不进行访问//函数会找到第一个分隔符并记住位置下次找就从这个位置开始找12.strerror函数的使用
strerror可以将错误对应的错误信息字符的地址返回
strerror 函数可以把参数部分错误码对应的错误信息的字符串地址返回来。
在不同的系统和C语⾔标准库的实现中都规定了⼀些错误码⼀般是放在 errno.h 这个头⽂件中说明的C语⾔程序启动的时候就会使⽤⼀个全局的变量errno来记录程序的当前错误码只不过程序启动的时候errno是0表⽰没有错误当我们在使⽤标准库中的函数的时候发⽣了某种错误就会将对应的错误码存放在errno中⽽⼀个错误码的数字是整数很难理解是什么意思所以每⼀个错误码都是有对应的错误信息的。strerror函数就可以将错误对应的错误信息字符串的地址返回。
//int main()
//{
// for (int i 0; i 10; i)
// {
// printf(%d:%s\n, i,strerror(i));
// }
// return 0;
//}//0:No error
//1:Operation not permitted
//2 : No such file or directory
//3 : No such process
//4 : Interrupted function call
//5 : Input / output error
//6 : No such device or address
//7 : Arg list too long
//8 : Exec format error
//9 : Bad file descriptorint main()
{//打开文件FILE*pffopen(date.txt, r);//r---读以读文件的形式打开文件如果文件不存在就是打开失败//打开失败就返回一个空指针if (pf NULL)//打开失败{printf(打开文件失败原因是%s,strerror(errno));//为了使用errno我们要包含头文件#include errno.hreturn 1;//打开失败我们就直接结束进程}else{printf(打开成功\n);fclose(pf);//关闭文件pf NULL;}return 0;
}
//打开文件失败原因是No such file or directorystrerror---将错误码对应的错误信息的字符串的起始地址返回
int main()
{//打开文件FILE*pffopen(date.txt, r);//r---读以读文件的形式打开文件如果文件不存在就是打开失败//打开失败就返回一个空指针if (pf NULL)//打开失败{printf(打开文件失败原因是:%s\n,strerror(errno));//为了使用errno我们要包含头文件#include errno.hperror(打开文件失败原因是);return 1;//打开失败我们就直接结束进程}else{printf(打开成功perror--将errno中错误信息直接打印出来
perror函数线打印str指向的字符串再打印冒号再打印空格再打印错误码对应的信息