C语言学习之字符串、字符和字节第三讲
来源:互联网 发布:seo 教程 编辑:程序博客网 时间:2024/05/19 17:24
1.错误信息
1.1函数原型:char *strerror( int error_number );
函数功能:当你调用一些函数时,请求操作系统执行一些功能如打开文件时,如果出现错误,操作系统是通过设置一个外部整型变量errno进行错误代码报告的。strerror函数是吧其中的一个错误代码作为参数并返回一个指向用于描述错误的字符串的指针。事实上返回值应该被声明为const,因为你不应该修改它。
#include <stdio.h> // void perror(const char *msg);
#include <string.h> // char *strerror(int errnum);
#include <errno.h> //errno
perror是错误输出函数,输出格式为:msg:errno对应的错误信息(加上一个换行符);
strerror 是通过参数 errnum (就是errno),返回对应的错误信息。
errno 是错误代码,在 errno.h头文件中;
以下是测试程序:
--------------------------------------------------------------------
// perror , strerror 函数 , errno 测试
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int main(int argc, char *argv[])
{
FILE *fp;
char *buf;
if( (fp = fopen(argv[1], "r")) == NULL)
{
perror("perror"); // 好方便
errno = 12;
printf("strerror: %s\n", strerror(errno)); //转换错误码为对应的错误信息
exit(1);
}
perror("perror");
errno = 13;
printf("strerror: %s\n", strerror(errno));
fclose(fp);
return 0;
}
--------------------------------------------------------------------
输入一个存在的文件名,如:./a.out 111
perror: No such file or directory
strerror: Cannot allocate memory
perror: Success
strerror: Permission denied
open失败则会输出:
open成功则会输出:
很明显,perror信息是由 perror函数输出的了,第二行是 strerror通过将 errno 轮换成对应的错误信息打印出来。
参考链接Standard C 语言标准函数库速查
用户组函数
2.字符操作
2.1字符分类
C语言中<ctype.h> ,在C++中为<cctype>
本文下面列出这个头文件的常用函数。目的是了解字符判断函数和学习简洁代码编写。
注意:C++中的<cctype>和<cwtype>头文件继承于C。在许多实现方式中,函数在s记命名空间内部和外部都定义了,
以允许旧式C程序编译和链接。此时,函数名无论是否带std限定符都能工作,但因为我们编写的是C++程序,所以应
限定名称。
isalnum() 如果参数为字母数字,则返回ture
isalpha() 如果参数为字母,则返回ture
iscntrl() 如果参数为控制字符,则返回ture
isdigit() 如果参数为数字(0-9),则返回ture
isgraph() 如果参数为空格之外的打印字符,则返回ture
islower() 如果参数是小写字母,则返回ture
isprint() 如果参数为打印字符,包括空格,则返回ture
ispunct() 如果参数为标点符号,则返回ture
isspace() 如果参数为标准空白字符(空格,进纸,换行符,回车,水平制表符,垂直制表符),则返回ture
siupper() 如果参数为大写字母,则返回ture
isxdigit() 如果参数为十六进制数,则返回ture
tolower() 如果参数为大写字母,即转化为小写字母,否则返回原值
toupper() 如果参数为小写字母,即转化为大写字母,否则返回原值
// 判断字符c是否为英文字母:::0x41 0x61,如果是大写字母,
// 将通过(ch | 0x20)转为小写字母值来判断
int isalpha(int ch )
{
return (unsigned int)((ch | 0x20) - 'a') < 26u;
}
// *******************************************************
// 判断字符c是否为大写英文字母
int isupper( int ch )
{
return (unsigned int)(ch - 'A') < 26u;
}
// *******************************************************
// 判断字符c是否为小写英文字母
int islower ( int ch )
{
return (unsigned int) (ch - 'a') < 26u;
}
// *******************************************************
// 判断字符c是否为数字
int isdigit( int ch )
{
return (unsigned int)(ch - '0') < 10u;
}
// *******************************************************
// 判断字符c是否为十六进制数字。
// 当c为A-F,a-f或0-9之间的十六进制数字时,返回非零值。
int isxdigit( int ch )
{
return (unsigned int)( ch -'0') < 10u ||
(unsigned int)((ch | 0x20) - 'a') < 6u;
}
// *******************************************************
// 判断字符c是否为空白符。空白符指空格、水平制表、垂直制表、换页、回车和换行符。
int isspace( int ch )
{
return (unsigned int)(ch - 9) < 5u || ch == ' ';
}
// *******************************************************
// 判断字符c是否为标点符号。标点符号指那些既不是字母数字,也不是空格的可打印字符。
int ispunct( int ch )
{
return isprint(ch) && !isalnum (ch) && !isspace (ch);
}
// *******************************************************
// 测试参数ch是否是字母(A-Z,大小写均可)或数字(0-9)
int isalnum ( int ch )
{
return (unsigned int)((ch | 0x20) - 'a') < 26u ||
(unsigned int)( ch - '0') < 10u;
}
// *******************************************************
// 判断字符c是否为可打印字符(含空格)。当c为可打印字符(0x20-0x7e)时,
// 返回非零值,否则返回零。
int isprint( int ch )
{
return (unsigned int)(ch - ' ') < 127u - ' ';
}
// *******************************************************
// 判断字符c是否为除空格外的可打印字符。可打印字符(0x21-0x7e)
int isgraph( int ch )
{
return (unsigned int)(ch - '!') < 127u - '!';
}
// *******************************************************
// 判断字符c是否为控制字符。当c在0x00-0x1F之间或等于0x7F(DEL)时,
// 返回非零值,否则返回零。
int iscntrl( int ch )
{
return (unsigned int)ch < 32u || ch == 127;
}
// *******************************************************
// 小写字母转换为大写字母。
int toupper( int ch)
{
if ( (unsigned int)(ch - 'a') < 26u )
ch += 'A' - 'a';
return ch;
}
// 返回一个按位与不就行了吗??简练为好,不做检测
// return (unsigned int)(ch | 0x20);
// tolower 类似表示为 return (unsigned int)(ch & 0x5F);
// *******************************************************
// 大写字母转换为小写字母。
int tolower( int ch)
{
if ( (unsigned int)(ch - 'A') < 26u )
ch += 'a' - 'A';
return ch;
}
// *******************************************************
// 判断字符c是否为ascii码。ascii码指0x00-0x7F之间的字符。
int isascii( int ch )
{
return (unsigned int)ch < 128u;
}
//*******************************************************
//将字符c转换为ascii码。toascii函数将字符c的高位清零,仅保留低七位。返回转换后的数值。
int toascii( int c)
{
return c & 0x7f;
}
//*******************************************************
//判断字符c是否为英文字母和下划线
int iscsymf(int c)
{
return (isalpha(c) || ( c == '_' ));
}
// *******************************************************
// 判断字符c是否为英文字母、数字和下划线
int iscsym(int c)
{
return (isalnum(c) || ( c == '_' ));
}
2.2字符转换
函数原型:int tolower ( int ch);
函数功能: 函数把大写字母转换为小写字母,tolower函数函数返回其参数的对应小写形式。如果不是处于大写字母,函数不修改直接返回。
函数原型:int toupper ( int ch);
函数功能: 函数把小写字母转换为大写字母,tolower函数函数返回其参数的对应大写形式。如果不是处于小写字母,函数不修改直接返回。
范例:将s 字符串内的大写字母转换成小写字母。
- #include <ctype.h>
- main(){
- char s[] = "aBcDeFgH12345;!#$";
- int i;
- printf("before tolower() : %s\n", s);
- for(i = 0; i < sizeof(s); i++)
- s[i] = tolower(s[i]);
- printf("after tolower() : %s\n", s);
- }
执行结果:
before tolower() : aBcDeFgH12345;!#$
after tolower() : abcdefgh12345;!#$
3.内存操作
3.1内存复制
函数原型: void *memcpy( void *dst , void const *src , size_t length);
函数功能:memcpy从src的起始位置赋值length个字节到dst的内存起始位置。函数返回一个指向dst第一个未知的指针。
- /*
- *copyright@nciaebupt 转载请注明出处
- *原型:void *memcpy(void *dest, const void *src, size_t count);
- *用法:#include <cstring>
- *功能:由src所指内存区域复制count个字节到dest所指内存区域。
- *说明:src和dest所指内存区域不能重叠,函数返回指向dest的指针。
- *使用C函数库中的memcpy
- *
- */
- #include <cstdio>
- #include <cstring>
- int main(int args,char ** argv)
- {
- char * src = "Hello world!";
- char dest[20];
- /*这里使用strlen(src)+1是因为strlen(src)返回的是src的字符的个数,不包括结束符\0
- *而我们复制时希望将\0一起复制,故需要将strlen(src)加1
- */
- memcpy(dest,src,strlen(src)+1);
- printf("The dest is : %s\n",dest);
- getchar();
- return 0;
- }
- /*
- *copyright@nciaebupt 转载请注明出处
- *原型:void *memcpy(void *dest, const void *src, size_t count);
- *用法:#include <cstring>
- *功能:由src所指内存区域复制count个字节到dest所指内存区域。
- *说明:src和dest所指内存区域不能重叠,函数返回指向dest的指针。
- *自己实现memcpy
- */
- #include <cstdio>
- #include <cstring>
- void * _memcpy(void *dest,const void * src,size_t count)
- {
- while(count--)
- {
- *((char *)dest) = *((char *)src);
- (char *)(dest = (char *)dest + 1);
- (char *)(src =(char *)src + 1);
- }
- }
- int main(int args,char ** argv)
- {
- char * src = "Hello World!";
- char dest[20];
- /*这里使用strlen(src)+1是因为strlen(src)返回的是src的字符的个数,不包括结束符\0
- *而我们复制时希望将\0一起复制,故需要将strlen(src)加1
- */
- _memcpy(dest,src,strlen(src) + 1);
- printf("The length is : %d",strlen(src));
- printf("The dest is : %s",dest);
- getchar();
- return 0;
- }
参考博客C函数库中的memcpy实现
- /*
- *copyright@nciaebupt 转载请注明出处
- *c标准库中的函数memccpy
- *原型:extern void *memccpy(void *dest, void *src, unsigned char ch, unsigned int count);
- *用法:#include <string.h>
- *功能:由src所指内存区域复制不多于count个字节到dest所指内存区域,如果遇到字符ch则停止复制。
- *说明:返回指向字符ch后的第一个字符的指针,如果src前n个字节中不存在ch则返回NULL。ch被复制。
- *使用C函数库中的memccpy
- */
- #include <cstdio>
- #include <cstring>
- int main(int args,char ** argv)
- {
- char *s="Golden Global View";
- char d[20],*p;
- p = (char *)memccpy(d,s,'e',strlen(s));
- if(p)
- {
- *p='\0'; //给d添加一个结束符\0
- printf("Char found: %s\n",d);
- }
- else
- printf("Char not found.\n");
- getchar();
- return 0;
- }
- /*
- *copyright@nciaebupt 转载请注明出处
- *c标准库中的函数memccpy
- *原型:extern void *memccpy(void * dest,const void * src,int c,unsigned count);
- *用法:#include <string.h>
- *功能:由src所指内存区域复制不多于count个字节到dest所指内存区域,如果遇到字符ch则停止复制。
- *说明:返回指向字符ch后的第一个字符的指针,如果src前n个字节中不存在ch则返回NULL。ch被复制。
- *自己重写memccpy
- */
- #include <cstdio>
- #include <cstring>
- void * _memccpy(void * dest, const void * src, int c,unsigned count)
- {
- while(count && (*((char *)(dest = (char *)dest + 1) - 1) =
- *((char *)(src = (char *)src + 1) -1)) != (char)c)
- {
- count--;
- }
- return (count ? dest : NULL);
- }
- int main(int args,char ** argv)
- {
- char * src = "Golden Global View";
- char dest[20],*p;
- p = (char *)memccpy(dest,src,'d',strlen(src));
- if(p)
- {
- *p = '\0';
- printf("Char found: %s\n",dest);
- }
- else
- {
- printf("Char not found.\n");
- }
- getchar();
- return 0;
- }
函数返回一个指向
dest
的指针
3.2内存移动
函数原型: void *memmove( void *dst , void const *src , size_t length);
函数功能:memmove用于从src拷贝count个字符到dst,如果目标区域和源区域有重叠的话,memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中。但复制后src内容会被更改。但是当目标区域与源区域没有重叠则和memcpy函数功能相同。
- /*
- *copyright@nciaebupt 转载请注明出处
- *原型:void *memmove(void *dest, const void *src, size_t count);
- *用法:#include <string.h>
- *功能:由src所指内存区域复制count个字节到dest所指内存区域。
- *说明:src和dest所指内存区域可以重叠,但复制后src内容会被更改。函数返回指向dest的指针。
- *使用C函数库中的memmove
- *
- */
- #include <cstdio>
- #include <cstring>
- int main(int args,char ** argv)
- {
- char src[] = "memmove can be very useful......";
- char dest[40] ={""};
- memmove(src + 20,src + 15,11);
- printf("%s\n",src);
- getchar();
- return 0;
- }
- /*
- *copyright@nciaebupt 转载请注明出处
- *原型:void *memmove(void *dest, const void *src, size_t count);
- *用法:#include <string.h>
- *功能:由src所指内存区域复制count个字节到dest所指内存区域。
- *说明:src和dest所指内存区域可以重叠,但复制后src内容会被更改。函数返回指向dest的指针。
- *自己实现memmove
- *
- */
- #include <cstdio>
- #include <cstring>
- void * _memmove(void * dest, const void * src, size_t count)
- {
- void * ret = dest;
- if((char *)dest <= (char *)src ||(char *)dest >= ((char *)src) + count)
- {//如果数据区没有重合,则从低地址向高地址复制
- while(count--)
- {
- *((char *)dest) = *((char *)src);
- dest = (char *)dest + 1;
- src = (char *)src + 1;
- }
- }
- else//如果数据区有重合,则从高地址向低地址复制
- {
- dest = (char *)dest + count - 1;
- src = (char *)src + count - 1;
- while(count--)
- {
- *((char *)dest) = *((char *)src);
- dest = (char *)dest - 1;
- src = (char *)src -1;
- }
- }
- return ret;
- }
- int main(int args,char ** argv)
- {
- char src[] = "memmove can be very useful......";
- char dest[40] ={""};
- _memmove(src + 20,src + 15,11);
- printf("%s\n",src);
- getchar();
- return 0;
- }
C函数库中的memmove实现
3.3内存比较
函数原型: void *memcmp( void const *a , void const *b , size_t length);
函数功能:memcmp对两段内存的内容进行比较,这两段内存分别起始于a和b,共比较length个字节。这些值按照五福好字符逐字节比较,函数的返回类型和strcmp函数一样--赋值表示a小于b,正值表示a大于b,零表示相等。由于这些值是根据一串无符号字节进行比较的,所以如果memcmp寒素用于比较不是单字节的数据如浮点型或者这逆行就可能给出不可预知的结果。
- /*
- *copyright@nciaebupt 转载请注明出处
- *原型:int memcmp(const void *buf1, const void *buf2, size_t count);
- *用法:#include <string.h>
- *功能:比较内存区域buf1和buf2的前count个字节。
- *说明:
- * 当buf1<buf2时,返回值<0
- * 当buf1=buf2时,返回值=0
- * 当buf1>buf2时,返回值>0
- *使用C函数库中的memcmp
- */
- #include <cstdio>
- #include <cstring>
- int main(int args,char ** argv)
- {
- char str1[] = "Hello World!";
- char str2[] = "Hello world!";
- int flag = memcmp(str1,str2,sizeof(str1));
- if(flag < 0) printf("%s is less than %s\n",str1,str2);
- else if(flag == 0) printf("%s is equal %s",str1,str2);
- else printf("%s is larger than %s",str1,str2);
- getchar();
- return 0;
- }
- /*
- *copyright@nciaebupt 转载请注明出处
- *原型:int memcmp(const void *buf1, const void *buf2, size_t count);
- *用法:#include <string.h>
- *功能:比较内存区域buf1和buf2的前count个字节。
- *说明:
- * 当buf1<buf2时,返回值<0
- * 当buf1=buf2时,返回值=0
- * 当buf1>buf2时,返回值>0
- *自己实现memcmp
- */
- #include <cstdio>
- int _memcmp(const void * buf1,const void * buf2,size_t count)
- {
- if(!count)
- return 0;
- while(count-- && *((char *)buf1) == *((char *)buf2))
- {
- buf1 = (char *)buf1 + 1;
- buf2 = (char *)buf2 + 1;
- }
- return (*((char *)buf1)-*((char *)buf2));
- }
- int main(int args,char ** argv)
- {
- char str1[] = "Hello World!";
- char str2[] = "Hello world!";
- int flag = _memcmp(str1,str2,sizeof(str1));
- if(flag < 0) printf("%s is less than %s\n",str1,str2);
- else if(flag == 0) printf("%s is equal %s",str1,str2);
- else printf("%s is larger than %s",str1,str2);
- getchar();
- return 0;
- }
C函数库中的memcmp实现
3.4 内存查询
函数原型: void *memchr( void const *a ,int ch , size_t length);
函数功能:memchr是从a的起始位置开始查找字符ch第一次出现的位置,并返回一个指向该位置的指针,他共查找length个字节。如果这个length个字节中都未找到该字符,函数返回一个NULL指针。
- /*
- *copyright@nciaebupt 转载请注明出处
- *原型:void *memchr(const void *buf, int ch, size_t count);
- *用法:#include <string.h>
- *功能:从buf所指内存区域的前count个字节查找字符ch。
- *说明:当第一次遇到字符ch时停止查找。
- * 如果成功,返回指向字符ch的指针;否则返回NULL。
- *使用C函数库中的memchr
- */
- #include <cstdio>
- #include <cstring>
- int main(int args,char ** argv)
- {
- char s[] = "simple string";
- char *p = (char *)memchr(s,'n',strlen(s));
- if(p != NULL)
- printf("find the ch in position : %d\n",p - s + 1);
- else printf("not find the ch!\n");
- getchar();
- return 0;
- }
- /*
- *copyright@nciaebupt 转载请注明出处
- *原型:void *memchr(const void *buf, int ch, size_t count);
- *用法:#include <string.h>
- *功能:从buf所指内存区域的前count个字节查找字符ch。
- *说明:当第一次遇到字符ch时停止查找。
- * 如果成功,返回指向字符ch的指针;否则返回NULL。
- *自己实现memchr
- */
- #include <cstdio>
- void * _memchr(const void *buf,int ch,size_t count)
- {
- while(count && (*(unsigned char *)buf != (unsigned char )ch))
- {
- buf = (unsigned char *)buf + 1;
- count--;
- }
- return (count ? (void *)buf : NULL);
- }
- int main(int args,char ** argv)
- {
- char s[] = "simple string";
- char *p = (char *)_memchr(s,'n',sizeof(s));
- if(p != NULL)
- printf("find the ch in position : %d\n",p - s + 1);
- else printf("not find the ch!\n");
- getchar();
- return 0;
- }
C函数库中的memchr实现
3.4 内存设置指定字符
函数原型: void *memset( void *a , int ch , size_t length);
函数功能:memset函数把从a开始的length个字节都设置为字符值ch
例如
memset( buffer , 0 , SIZE);
把buffer的前SIZE个字节都初始化为0。
字符串由NUL字节结尾,所以字符串内部不能包含任何NUL字符。但是,非字符串数据内部包含零值得情况并不罕见。你就无法用字符串函数处理这类数据,因为当他门遇到第一个NUL自解释将停止工作。由此产生了以上函数用于处理任意字节序列。
- C语言学习之字符串、字符和字节第三讲
- C语言学习之字符串、字符和字节第一讲
- C语言学习之字符串、字符和字节第二讲
- C语言学习第十讲-字符和字符串
- C语言学习之关键字第三讲
- C语言提高-30讲:字符和字符串处理函数
- C语言中的字符串,字符和字节函数
- C语言学习笔记之 第三讲:人机交互
- C语言学习之输入/输出函数第三讲
- C语言提高-28讲: 字符串、字符数组、字符指针
- C语言第三讲
- 【c基础】字符串、字符和字节
- c和指针 -- 字符串、字符、字节
- (转)C语言学习札记(5)-- 字符和字符串
- 字符串,字符和字节
- 字符串,字符和字节
- 《C和指针》学习笔记五/数组、字符串字符和字节/
- C语言学习之关键字第一讲
- 【Bash百宝箱】Android编译系统(Makefile)
- Redis学习记录之命令Set(十二)
- WebApplicationContext初始化的三种方式
- SQl -维护数据的完整性--约束 -
- REST技术第一步 Hello world!
- C语言学习之字符串、字符和字节第三讲
- iOS UITableView 隐藏多余分割线
- Snort的TILE64移植
- IOS UICollectionView didselect促发不到
- 如何用git管理自己的代码
- 程序员开发进阶的书单
- 第1章第2节练习题16 归并并逆序单链表
- CImage从资源中加载图片文件
- java 演示使用jdbc-odbc桥连接的方式操作数据库 向数据库中添加数据