C语言库函数相关

计算机考研机试笔记之C/C++基础2


参考书籍:
计算机考研复试上机指导全书.天勤计算机考研系列.孙肇博 张飞飞.2014.01

C语言库函数

stdio.h

  1. sscanf()
    从已知字符串buffer中获取与指定格式相符的数据,函数原型如下:
    int sscanf(const char *buffer, const char *format, ...);
    
    示例:
    #include <stdio.h>
    int main() {
    	char buf[] = "2019,w:c:b";
    	int a;
    	char b,c,d;
    	sscanf(buf,"%d,%c:%c:%c",&a,&b,&c,&d);
    	printf("%d_%c_%c_%c",a,b,c,d);	
    	return 0;
    }
    
    输出结果:
    2019_w_c_b
    
    此函数可以用来将字符串类型表示的数据,转换为其他类型。
  2. sprintf()
    将数据按照一定格式写入字符串,函数原型如下:
    int sprintf(char *buffer, const char *format, ...);
    
    示例:
    计算已知的两小数之和,并将结果的第一位小数输出
    #include <stdio.h>
    int main() {
    	char buf[10];
    	double a = 1.23456, b = 1.23456;
    	sprintf(buf,"%f",a+b);
    	int i = 0;
    	while(buf[i++] != '.');
    	printf("%s\n",buf);
    	printf("%c",buf[i]);
    	return 0;
    }
    
    输出结果:
    2.469120
    4
    
    此函数中的buffer,包含”\0“,因此在设置数组时,数组长度要加一。
  3. ungetc()
    把字符 char(一个无符号字符)推入到指定的流 stream 中,使它成为下一个被读取到的字符。函数原型如下:
    int ungetc(int char, FILE *stream);
    
    示例:
    #include <stdio.h>
    int main() {
    	char ch;
    	int num;
    	while((ch = getchar()) != '\n'){
    		if(ch == ' ')//过滤空格
    			continue;
    		ungetc(ch,stdin);//将获取的字符ch退回到stdin流 
    		scanf("%d",&num);//从stdin中读取数据,以int类型存入num变量 
    		printf("_%d_ ",num);
    	}
    	return 0;
    }
    
    输出结果:
    20 15 14 17
    _20_ _15_ _14_ _17_
    
    该函数的作用,我比较认同以下这个说法:
    当从流中读出字符,但不是所需内容时,为了不改流的内容,需要回写入流中。写回后再读,仍会读出来。1
    注意:
    ungetc 不能连续多次调用。两次 ungetc 调用之间必须至少有一次读操作或者文件指针移动操作(fseek,rewind 等 ) ,ungetc 只影响输入流,而不影响与输入流关联的外存文件。
  4. freopen()
    用于重定向输入输出流。该函数可以在不改变代码原貌的情况下改变输入输出环境,但使用时应当保证流是可靠的。函数原型如下:
    FILE *freopen(const char *fname, const char *mode, FILE *stream);
    
    示例:
    #include <stdio.h>
    int main() {
    	freopen("in.txt","r",stdin);//输入重定向,输入数据将从当前目录下的in.txt文件中读取 
    	char ch;
    	while((ch = getchar()) != EOF){
    		printf("%c",ch);
    	}
    	fclose(stdin);//关闭重定向输入
    	return 0;
    }
    
    in.txt文件内容:
    in.txt内容
    输出结果:
    123456wertyui
    

stdlib.h

  1. atof()
    把用字符串表示的浮点数(或整数)转换为double型的数据。函数原型如下:
    double atof(const char *str);
    
    示例:
    #include <stdio.h>
    #include <stdlib.h> 
    int main() {
    	char *str1 = "11.62";
    	char *str2 = "-11.62";
    	char *str3 = "11.62e-2";
    	char *str4 = "11.62abc1.26";
    	char *str5 = "a11.62";
    	
    	double a,b,c,d,e;
    	
    	a = atof(str1);
    	b = atof(str2);
    	c = atof(str3);
    	d = atof(str4);
    	e = atof(str5);
    	printf("%lf\n%lf\n%lf\n%lf\n%lf",a,b,c,d,e); 
    
    	return 0;
    }
    
    输出结果:
    11.620000
    -11.620000
    0.116200
    11.620000
    0.000000
    
    注意:待转换的字符串必须是有效的整数或浮点数(正负均可)开头才能转换成功。上例中str5不是以有效数字开头,因此无法转换。
  2. malloc()和free()
    malloc()申请系统内存空间,申请成功返回新开辟内存空间的首地址,申请失败返回NULL。
    free()释放内存空间。二者函数原型如下:
    void *malloc(size_t size);
    void free(void *ptr);
    
    示例:
    #include <stdio.h>
    #include <stdlib.h> 
    int main() {
    	struct sqlist{
    		int data;
    		struct sqlist *next;
    	};
    	sqlist *p;
    	p = (sqlist *)malloc(sizeof(sqlist));//对返回值一定要进行强制类型转换,函数参数为申请的内存空间大小
    	//做一些操作……
    	free(p);
    	return 0;
    } 
    
  3. qsort()
    快速排序,后面提及排序时具体讲解。

string.h

  1. strlen()
    获取字符串长度,不包括”\0“。

    unsigned int strlen(char *str);
    

    示例:

    #include <stdio.h>
    #include <string.h> 
    int main() {
    	char c[] = "welcome";
    	printf("%d",strlen(c));
    	return 0;
    } 
    

    输出结果:

    7
    

    注:strlen()是一个函数,需要进行函数调用;而sizeof()是单目运算符,在编译时计算缓冲区的长度,因此 sizeof ()不能用来返回动态分配的内存空间的大小

    实现strlen()函数功能:见”C语言:三种方法模拟实现strlen函数“2

  2. strcmp()
    从左往右比较str1str2两个字符串对应位置的ASCII码值的大小。当值不同时,或遇到结束符时,返回结果。当str1 < str2时,返回负数;当str1 = str2时,返回0;当str1 > str2时,返回正数。只能用于字符串的比较,不能用于各种类型的数组比较,函数原型如下:

    int strcmp(const char *str1, const char *str2);
    

    示例:

    #include <stdio.h>
    #include <string.h>
    int main() {
    	char *a = "acm";
    	char *b = "block";
    	char *c = "code";
    	printf("%d\n",strcmp(c,b)); 
    	printf("%d\n",strcmp(a,a));
    	printf("%d",strcmp(a,c)); 
    	return 0;
    } 
    

    输出结果:

    1
    0
    -1
    

    一种实现strcmp()函数功能的函数:

    #include <stdio.h>
    int strcmp_self(const char *str1, const char *str2){
    	//函数传入参数为const char* ,属于有符号数 
    	while(*str1 && *str2 && (*str1 == *str2)){
    		str1++;
    		str2++;
    	}
    	if(*(unsigned char *)str1 > *(unsigned char *)str2)
    	//由于该函数参数为有符号数,但字符串的ASCII码无负值
    	//若不转换,比较的时候会出现错误 
    	//因此要使用unsigned char*强制转换为无符号数 
    		return 1;
    	else if(*(unsigned char *)str1 < *(unsigned char *)str2)
    		return -1;
    	else
    		return 0;
    } 
    int main() {
    	char *a = "acm";
    	char *b = "block";
    	char *c = "code";
    	printf("%d\n",strcmp_self(c,b)); 
    	printf("%d\n",strcmp_self(a,a));
    	printf("%d",strcmp_self(a,c)); 
    	return 0;
    	return 0;
    } 
    

    运行结果同上。

  3. strcpy()
    将以from为首地址的字符串连同’\0’,复制到以to为首地址的存储空间,只能拷贝字符串,不能用于各种类型的数组复制,原型如下:

    char *strcpy(char *to, const char *from);
    

    函数实现:

    #include <stdio.h>
    #include <assert.h>
    char *strcpy_self(char *to, const char *from){
    	assert((to != NULL) && (from != NULL));
    	char *ret = to;
    	while((*ret++ = *from++) != '\0');
    	return to;
    } 
    int main() {
    	char a[6] = "good";
    	char b[6] = "bad";
    	//此处未使用指针形式,大家也请注意
    	//通过char *指针修改字符串常量中的字符会导致Segment fault错误
    	//原因是char *a = "good",good的存储位置是只读的内存地址
    	//不允许执行以下的strcpy()操作
    	printf("%s\t%s\n",a,b);
    	strcpy_self(a,b);
    	printf("%s\t%s\t",a,b);
    	return 0;
    } 
    

    输出结果:

    good    bad
    bad     bad
    

    与strcpy()相似的有一个strncpy()的函数,该函数功能类似,只不过strncpy拷贝的是字符,最后一个’\0’没有拷贝,所以拷贝的时候需要对串进行清零处理,在最后加‘\0’,一定要养成好习惯。同时,使用strncpy()时,一定要防止内存重叠。其实现如下,将以src为首地址的字符串中的前n个字符拷贝到dest所指的数组中,并返回数组首地址:

    #include <stdio.h>
    #include <assert.h>
    char *strncpy_self(char *dest,const char *src,int n)
    {
    	assert((dest!=NULL)&&(src!=NULL));
    	char *cp=dest;
    	while(n&&(*cp++=*src++)!='\0')
    	{
    		n--;
    	}
    	if(n)
    	{
    		while(--n)
    		*cp++='\0';
    	}
    	return dest;
    }
    int main() {
    	char a[6] = "good";
    	char b[6] = "bad";
    	printf("%s\t%s\n",a,b);
    	strncpy_self(a,b,2);
    	printf("%s\t%s\t",a,b);
    	return 0;
    } 
    
  4. strcat()
    将以str2为首地址的字符串(包括’\0’)追加到以str1为首地址的字符串后面(删除*str1后面的’\0’),其函数原型如下:

    char *strcat(char *str1,const char *str2);
    

    我一般不使用strcat(),容易把自己搞糊涂,弄不清楚字符串内容最终成为了什么,或者造成内存溢出等错误,故习惯直接在主函数中写一遍:

    #include <cstdio>
    int main() {
    	char a[15] = "good";
    	char b[15] = "bad";
    	printf("%s\t%s\n",a,b);
    	//函数实现将字符数组 b 的内容追加到字符数组 a
    	//数组 a 一定要足够大,足以放下追加的内容
    	int i = 0, j = 0;
    	while(a[i++]);
    	i--;
    	while(b[j]){
    		a[i++] = b[j++];
    	}
    	a[i] = '\0';//补充结束符
    	printf("%s\t%s\t",a,b);
    	return 0;
    } 
    

    输出结果:

    good    bad
    goodbad bad
    	```	
    
  5. strstr()
    判断字符串*str2是否是*str1的子串,返回一个指针,指向字符串*str2在字符串*str1中出现的首位置,否则返回NULL。函数原型如下:

    const char *strstr(const char *str1,const char *str2);
    

    函数实现:

    #include <stdio.h>
    #include <assert.h>
    const char *strstr_self(const char *str1,const char *str2){
        const char *p1;
        const char *p2;
        if(!str1 || !str2)
        {
            return NULL;
        }
        //遍历str1字符串
        while(*str1)
        {
            //遍历子串
            p1 = str1;
            p2 = str2;
            do
            {
                if(!*p2)  //到了str2的结束位置,返回str1的位置
                    return str1;
            }while(*p1++ == *p2++);
            str1++;
        }
        return NULL;
    }
    int main() {
    	char a[15] = "good";
    	char b[15] = "ood";
    	printf("%s\t%s\n",a,b);
    	const char *c = strstr_self(a,b);
    	printf("%s",c);
    	return 0;
    } 
    
  6. strtok()
    用*str2中字符将*str1字符串分割,返回指针,指向分割下来的字符串首地址,若无分割下来的字符串,返回NULL。函数原型如下:

    char *strtok(char *str1,const char *str2);
    

    示例:

    #include <stdio.h>
    #include <string.h>
    int main() {
    	char a[] = "see you tomorrow";
    	char b[] = " ";
    	printf("%s\t%s\n",a,b);
    	char *res = NULL;
    	res = strtok(a,b);
    	while(res != NULL){
    		//注意,第一次调用strtok()函数时,第一个参数时str1
    		//但是之后调用时,第一个参数要改为NULL 
    		printf("%s\n",res);
    		res = strtok(NULL,b);
    	}
    	return 0;
    } 
    

    输出结果:

    see you tomorrow
    see
    you
    tomorrow
    
  7. memset()
    将一段内存置为某个值,**常用!**函数原型为:

    void *memset(void *buffer, int ch, size_t count);
    

    示例:

    #include <stdio.h>
    #include <string.h>
    int main() {
    	char a[] = "see you tomorrow";
    	printf("%s\n",a);
    	memset(a,'b',6); 
    	//将字符串数组 a 的前6个字符置为字符'b' 
    	printf("%s\n",a);
    	return 0;
    } 
    

    输出结果:

    see you tomorrow
    bbbbbbu tomorrow
    

math.h

见下篇


  1. https://blog.youkuaiyun.com/hubi0952/article/details/6897503 ↩︎

  2. https://blog.youkuaiyun.com/windyj809/article/details/80037006 ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值