C语言知识-零零散散(二)

C语言知识-零零散散(二)

字符串处理函数

gets和puts函数

/*
功能:从输入缓冲区中读取一个字符串存储到字符指针变量 str 所指向的内存空间。
参数:char *str,str是一个指针变量名,也可以一个字符数组名。
返回值:读入成功,返回和参数str相同的指针;失败,返回NULL指针。
*/
char *gets(char *str);
/*
功能:输出字符串。
参数:s是要输出的字符串,可以字符指针变量名、字符数组名、或者是字符常量。
返回值:成功,该函数返回一个非负值,如果发生错误则返回-1。
*/
int puts(const char *s);

gets函数,从标准设备上获取一个字符串,字符串可以包括空格,直到接收到换行字符或者字符串结束标志才停止。此函数有一个比较严重的缺陷,不能检查数组是否能装下输入行。例如,定义一个字符数组 char str[10];,如果使用gets输入的字符串为“hello”,可以正常的获取,但是,如果输入的是"hello world!",此时gets函数就会访问未分配的内存空间,那么就会引起程序的错误。

puts函数,从标准设备上输出一个字符串,输出结果时自带\n换行符。

fgets和fputs函数

/*
功能:从 stream 流中读取 size 个字符存储到字符指针变量 s 所指向的内存空间。
参数:s表示一个字符串的首地址,size表示需要读取的字符串的长度,stream 表示从何种流中读取,可以是标准输入流 stdin(读取键盘输入的字符串),也可以是文件流。
返回值:返回一个指向字符串中第一个字符的地址的指针。
*/
char *fgets(char *s, int size, FILE *stream);
/*
功能:将str所指定的字符串写入到stream指定的文件中。
参数:s代表要输出的字符串的首地址,可以是字符数组名、字符指针变量名;stream 表示向何种流中输出,可以是标准输出流 stdout(即屏幕输出),也可以是文件流。
返回值:成功返回0,失败返回-1。
*/
int fputs(const char * str, FILE * stream);

fgets函数,如果输入字符串长度的大小小于原始指针对应区域的大小,会在字符串输入完成时自动加入"\n\0";如果输入字符串长度的大小大于等于原始指针对应区域的大小,等待字符串结束标志后,把数组的最后一个元素替换为'\0'

fputs函数,显示字符串,和puts函数相比,fgets可以向任何流输出,但是fputs函数输出时,系统不会自动添加换行符。

scanf和printf函数

/*
功能:从标准输入 stdin 读取格式化输入
参数:格式控制字符串,变量地址列表
返回值:返回正确格式输入变量的个数;遇到错误或者EOF时,返回-1。
*/
int  scanf( const char *format [,argument]... );
/*
功能:发送格式化输出到标准输出 stdout
参数:格式控制字符串,变量列表
返回值:如果成功,则返回写入的字符总数,否则返回一个负数。
*/
int printf(const char *format, ...)

scanf函数,当输入一个字符串时,该函数不接收空格字符,遇到空格认为是字符串的结束。函数的返回值,当按照格式输入时,返回正确输入的个数,当遇到第一个输入未成功读取时,后面的都不再接收,如果在接收n个数据时未成功读取,返回值为n-1;当遇到错误或者EOF(ctrl+z)时,返回-1。

scanf函数的其他用法(与正则表达式结合):

1.可以接收空格,遇到换行结束

char* arr[100];
scanf("%[^\n]", arr);

2.限定接收数据的宽度

char* arr1[100];
char* arr2[100];
scanf("%3s%4s", arr1, arr2); //当输入一串字符时,arr1接收前三个,紧接着arr2接收四个,其余的舍弃

int a, b;
scanf("%3d%4d", &a, &b);    // 从键盘输入一串数组,a取三位,b取四位。

3.屏蔽数据类型,%* d表示屏蔽数字,%*c表示屏蔽字符

char* arr[100];
scanf("%*d%s", arr);    // 屏蔽前面输入的数字
sacnf("%*c%s", arr);    // 屏蔽第一个输入的字符

4.屏蔽一个区间内定义的数据

char c;
scanf("%*[0-9]%c", &c); // 屏蔽0-9数字
scanf("%*[a-z]%c", &c); // 屏蔽a-z字母

printf函数的各种打印形式,如下面的例子:

printf("%10.3lf\n", 12.3456);  //当输出是数字时,m.n,小数点后表示精度,小数点前表示保留的总位数,如果m>n,输出的数字位数小于m时,不足的在左边补空格:当m<n时,整数部分正常输出,小数部分保留n位有效数字
printf("%06d\n", 66);    // 不足6位,在前面补0
printf("%6d\n", 66);     // 不足6位,在前面补空格,默认时右对齐
printf("%-6d\n", 66);    // 加上'-',输出方式为左对齐,不足6位,数字后面补空格
printf("%6s\n", "abc");  // 和数字的输出一样,不足6个字符,在字符串前面补空格
printf("%6.4s\n", "abcde"); // 对于输出字符串,m.n, m表示要输出的总长度,n表示保留几个字符

strlen函数

/*
功能:计算目标字符串长度,不包含字符串结束符‘\0’
参数:字符串首地址,可以时字符数组名,字符串指针变量,或者字符串常量
返回值:字符串s的长度,size_t为unsigned int类型
*/
size_t strlen(const char *s);

strlen函数所求的是字符串的实际长度,即不包含’\0‘,需要注意的是,strlen并不能求出字符数组的长度。可以看下面例子:

int a = strlen("hello");
char* s1 = "hello";
int b = strlen(s1);
char s2[] = "hello";
int c = strlen(s2);
char s3[10] = {'h','e','l','l','o','\0'}; 
int d = strlen(s3);
printf("%d, %d, %d, %d\n",a,b,c,d);

strcpy和strncpy函数

/*
功能:把src所指向的字符串复制到dest所指向的空间中,'\0'也会拷贝过去
参数:
	dest:目的字符串首地址
	src:源字符首地址
返回值:
	成功:返回dest字符串的首地址
	失败:NULL

*/
char *strcpy(char *dest, const char *src);
/*
功能:把src指向字符串的前n个字符复制到dest所指向的空间中,是否拷贝结束符看指定的长度是否包含'\0'。
参数:
	dest:目的字符串首地址
	src:源字符首地址
	n:指定需要拷贝字符串个数
返回值:
	成功:返回dest字符串的首地址
	失败:NULL
*/
char *strncpy(char *dest, const char *src, size_t n);

strcpy函数,把源字符串src拷贝到目的字符串dest中,拷贝的时候会把 '\0’也一起拷贝过去。这里需要注意的是,当目标字符串的长度比源字符串短时,会造成缓冲溢出的错误。所以使得strcpy进行字符串拷贝时,具有安全隐患。当调用strcpy时,可以判断函数的返回值是否为NULL,来确定调用是否成功。

char s1[] = "hello";
char s2[10];
if(strcpy(s2, s1) != NULL){
	printf("OK\n");
}

strcpy函数,会拷贝源字符串中的’\0’,如果目的字符串已经初始化了,并且比源字符串长,那么只会覆盖源字符串的长度,如下面的例子,输出的结果为输出字符串为 “hello”,但是s2中的内容并没有被覆盖掉,s2={’h‘,‘e’,‘l’’,‘l’,‘o’,’\0’,‘o’,r’’,‘l’,‘d’,’\0’}

char s1[] = "hello";
	char s2[] = "helloworld";
	int i=0;

	strcpy(s2, s1);
	printf("%s\n", s2);
	for(i=0; i<sizeof(s2); i++){
		printf("%c", s2[i]);
	}
	printf("\n");

strncpy函数,从源字符串中拷贝指定长度的字符到目的字符中,所以拷贝过程中,并不保证目的字符串以’\0’为结尾。所以我们在拷贝完成以后,需要手动的添加’\0’标志。

char s1[] = "hello world";
char s2[20];

strncpy(s2, s1, 11);
//s2[11] = 0;
s2[11] = '\0';

printf("%s\n",s2);

这里需要注意的是,如果源字符串的长度小于拷贝的长度n,那么会把目的字符串剩下的部分全部置为 0。如下面代码,s2的初始值是"sssssssssssssssssss",当把s1拷贝给s2时,由于s1的长度小于s2,所以s2接收到"hello world\0"后,把剩余的部分全部置为’\0‘。

char s1[] = "hello world";
char s2[20]  = "sssssssssssssssssss";
int i=0;

strncpy(s2, s1, 20);

printf("%s\n",s2);
for(i=0; i<20; i++){
    printf("%c", s2[i]);
}c
    printf("\n");

strcat和strncat函数

/*
功能:将src字符串连接到dest的尾部,‘\0’也会追加过去
参数:
	dest:目的字符串首地址
	src:源字符首地址
返回值:
	成功:返回dest字符串的首地址
	失败:NULL
*/
char *strcat(char *dest, const char *src);
/*
功能:将src字符串前n个字符连接到dest的尾部,‘\0’也会追加过去
参数:
	dest:目的字符串首地址
	src:源字符首地址
	n:指定需要追加字符串个数
返回值:
	成功:返回dest字符串的首地址
	失败:NULL
*/
char *strncat(char *dest, const char *src, size_t n);

strcat函数,把源字符串追加到目的字符串后,目的字符串的长度一定要大于等于两个字符串的长度和,否则会发生访问越界的错误。在追加的时候,目的字符串的’\0’会被覆盖掉,追加完成以后,然后再在结尾加入’’\0’。

char arr1[20] = "hello";
char arr2[] = "world";

char* arr = strcat(arr1, arr2);
printf("%s\n", arr1);
printf("%s\n", arr);

strncat函数,用于将n个字符追加到字符串的结尾,同样的目的字符要足够长,追加过程中,会把目的字符串最后的’\0’覆盖掉,字符追加完成后,再追加’\0’。

char arr1[10] = "hello";
char arr2[] = "world";

char* arr = strncat(arr1, arr2, 3);
printf("%s\n", arr1);
printf("%s\n", arr);

再使用strncat函数时,如果n大于源字符串的长度,那么只取’\0’结束符前的字符,示例如下:

char arr1[10] = "hello";
char arr2[] = "wo\0rld";

char* arr = strncat(arr1, arr2, 5);
printf("%s\n", arr1);
printf("%s\n", arr);

strcmp和strncmp函数

/*
功能:比较 s1 和 s2 的大小,比较的是字符ASCII码大小。
参数:
	s1:字符串1首地址
	s2:字符串2首地址
返回值:
	相等:0
	大于:>0
	小于:<0
*/
int strcmp(const char *s1, const char *s2);
/*
功能:比较 s1 和 s2 前n个字符的大小,比较的是字符ASCII码大小。
参数:
	s1:字符串1首地址
	s2:字符串2首地址
	n:指定比较字符串的数量
返回值:
	相等:0
	大于: > 0
	小于: < 0
*/
int strncmp(const char *s1, const char *s2, size_t n);

**strcmp函数,**比较两个字符串的大小,该函数的比较是以ASCII 码表上的顺序来决定。比较时,直到遇到不相同的字符或者’\0’,返回结果,根据返回结果来判断两个字符串是否相同。

char arr1[] = "hello";
char arr2[] = "world";

int res = strcmp(arr1, arr2);
if(!res){
    printf("equal\n");
}
else{
    printf("not equal\n");
}

**strncmp函数,**比较两个字符串的前n个字符,和strcmp的比较规则相同。

char arr1[] = "hello";
char arr2[] = "hello";

int res = strncmp(arr1, arr2, 2);
printf("%d\n", res);

strcmp和strncmp函数,在比较的时候,如果两个字符串长度相同,那么逐个字符的比较大小;如果字符串长度不同,在’\0’前,逐字符比较,遇到不同的直接返回结果;如果比较遇到’\0’还没有比较出结果,那么长的字符串大于短字符串。

char arr1[] = "hell";
char arr2[] = "hello";
char arr3[] = "helly";
char arr4[] = "hew";

int res1 = strcmp(arr1, arr2);
int res2 = strcmp(arr2, arr3);
int res3 = strcmp(arr3, arr4);

printf("%d\n", res1);
printf("%d\n", res2);
printf("%d\n", res3);

sprintff和sscanf函数

/*
功能:根据参数format字符串来转换并格式化数据,然后将结果输出到str指定的空间中,直到出现字符串结束符 '\0'  为止。
参数:
	str:字符串首地址
	format:字符串格式,用法和printf()一样
返回值:
	成功:实际格式化的字符个数
	失败: - 1
*/
int sprintf(char *str, const char *format [, argument, ...]);
/*
功能:从str指定的字符串读取数据,并根据参数format字符串来转换并格式化数据。
参数:
	str:指定的字符串首地址
	format:字符串格式,用法和scanf()一样
返回值:
	成功:参数数目,成功转换的值的个数
	失败: - 1
*/
int sscanf(const char *str, const char *format [, argument, ...]);

**sprintf函数,**将格式化的数据写入字符串。sprintf()会根据参数format,来转换并格式化数据,然后将结果复制到参数str 所指的字符串数组,直到出现字符串结束(’\0’)为止。

int a = 123;
char s[10];
char arr[] = "hello";

sprintf(s, "%d", a);
printf("%s\n", s);
sprintf(s, "%s%d", arr, a);
printf("%s\n", s);

sprintf与printf函数的区别:二者功能相似,但是sprintf函数打印到字符串中,而printf函数打印输出到屏幕上。

**sscanf函数,**从字符串中读取指定格式的数据。将参数str的字符串根据参数format字符串来转换并格式化数据。

char src1[10] = "123";
char src2[10] = "hello 123"; 
char str[10];

int a = 0;
sscanf(src1, "%d", &a);
printf("%d\n", a);
sscanf(src2, "%s %d", str, &a);
printf("%s\n", str);
printf("%d\n", a);

sscanf与scanf类似,都是用于输入的,只是后者以屏幕(stdin)为输入源,前者以固定字符串为输入源。

strchr和strstr函数

/*
功能:在字符串s中查找字母c出现的位置
参数:
	s:字符串首地址
	c:匹配字母(字符)
返回值:
	成功:返回第一次出现的c地址
	失败:NULL
*/
char *strchr(const char *s, int c);
/*
功能:在字符串haystack中查找字符串needle出现的位置
参数:
	haystack:源字符串首地址
	needle:匹配字符串首地址
返回值:
	成功:返回第一次出现的needle地址
	失败:NULL
*/
char *strstr(const char *haystack, const char *needle);

strchr和strstr函数,前者时查找一个字符在目标字符串中出现的位置,后者是查找一个字符串在目标字符串中出现的位置,两个函数都是返回第一次匹配后的地址,后面如有重复将不会继续查找。c

char s[] = "hello 111123";
char c = 'l';
char str[] = "11";

char* ptrc = strchr(s, c);
char* ptrs = strstr(s, str);

printf("%s\n", ptrc);
printf("%s\n", ptrs);

strtok函数

/*
功能:来将字符串分割成一个个片段。当strtok()在参数s的字符串中发现参数delim中包含的分割字符时, 则会将该字符改为\0 字符,当连续出现多个时只替换第一个为\0。
参数:
	str:指向欲分割的字符串
	delim:为分割字符串中包含的所有字符
返回值:
	成功:分割后字符串首地址
	失败:NULL
*/
char *strtok(char *str, const char *delim);

strtok()用来将字符串分割成一个个片段。参数str指向将要分割的字符串,参数delim 则为分割字符串,当strtok()在参数str的字符串中发现到参数delim 的分割字符时则会将该字符改为\0 字符(即,strtok函数会修改str字符串)。在第一次调用时,strtok()中的参数str指向要分解的字符串,往后的调用则将参数str设置成NULL。每次调用成功则返回下一个分割后的字符串指针。

char str[] = "www.swu.edu.cn";
int i=0;
char* p = strtok(str, ".");

while(p != NULL){
    printf("%s\n", p);
    p = strtok(NULL, ".");
}

for(i=0; i<sizeof(str); i++){c
    printf("%c", str[i]);
                            }
printf("\n");

通过上面的代码可以看出,str在每次分割后,其中的’.‘字符被替换成’\0’;每一次调用strtok函数,会以第一次查找到的’.'进行分割,并当前分割后的字符串指针。

atoi函数

/*
功能:atoi()会扫描nptr字符串,跳过前面的空格字符,直到遇到数字或正负号才开始做转换,而遇到非数字或字符串结束符('\0')才结束转换,并将结果返回返回值。
参数:
	nptr:待转换的字符串
返回值:成功转换后整数

*/
int atoi(const char *nptr);

atoi就是把nptr字符串转化为整数,类似的还有atol,atof函数。需要注意的是,参数nptr前面可以包含空格,但是不能包括字母,如果数字后面有字母可以把字母前的数字进行转化。

char s1[] = "100";
char s2[] = "  100";
char s3[] = "  100h100";
char s4[] = "123.456";

int num1 = atoi(s1);
int num2 = atoi(s2);
int num3 = atoi(s3);
int num4 = atoi(s4);
long num5 = atol(s1);
float num6 = atof(s4);

printf("%d\n", num1);
printf("%d\n", num2);
printf("%d\n", num3);
printf("%d\n", num4);
printf("%ld\n", num5);
printf("%f\n", num6);
  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值