0
点赞
收藏
分享

微信扫一扫

判断闰年(C语言)

沐之轻语 2024-03-19 阅读 19

目录

前言

一、字符分类函数

二、字符转换函数

三、strlen()函数

四、strcpy()函数

五、strcat()函数

六、strcmp()函数

七、strncpy()函数

八、strncat()函数

九、strncmp()函数

十、strstr()函数

十一、strtok()函数

十二、strerror()函数

总结


前言

今天我们来了解一下c语言中字符函数和字符串函数,和这些函数的模拟实验。

字符函数是处理字符型数据的函数,常见的字符函数有:

iscntrl():判断是否为控制字符

isdigit():判断是否为数字

islower():判断是否为小写字母

issupper():判断是否为大写字母

tolower():将大写字母转小写 

toupper():将小写字母转大写

字符串函数是处理字符串型数据的函数,常见的字符函数有:

strlen() :求字符串的长度

strcpy() :将一个字符串复制给另外一个字符串

strcat() :将一个字符串链接到另一个字符串的后面

strcmp() :比较两个字符串的大小

strstr() :查找一个字符串在另一个字符串中是否存在

strtok() :分割字符串,分为多个子串

strerror() :把参数部分错误码对应的错误信息的字符串地址返回来


一、字符分类函数

C语⾔中有⼀系列的函数是专门做字符分类的,也就是⼀个字符是属于什么类型的字符的。

这些函数的使⽤都需要包含⼀个头文件是 ctype.h

函数如果参数符合下列条件就返回真
iscntrl任何控制字符
isspace空白字符:空格‘ ’,换页符‘\f’,换行符'\n',回车符'\r',制表符‘\t'或者垂直字表符'\v'
isdigit十进制数字0~9
isxdigit十六进制数字,包括所有十进制,小写怎么a~f,大写字母A~F
islower小写字母a~z
isupper大小字母A~Z
isalpha字母a~z或A~Z
isalnum字母或者数字,a~z,A~Z,0~9
ispunct标点符号,任何不属于数字或字母的图形字符(可打印)
isgraph任何图形字符
isprint任何可打印字符,包括图形字符和空白字符

函数用法也十分简单:

 int islower ( int c );

islower 是能够判断参数部分的 c 是否是小写字母的。

通过返回值来说明是否是小写字母,如果是小写字母就返回非0的整数,如果不是小写字母,则返回0。

练习: 写⼀个代码,将字符串中的小写字母转大写,其他字符不变。

#include <stdio.h>
#include <ctype.h>
int main ()
{
   int i = 0;
   char str[] = "Test String.\n";
   char c;
   while (str[i])
  {
      c = str[i];
      if (islower(c)) 
         c -=32;
      putchar(c);
      i++;
   }
 return 0;
}

二、字符转换函数

在上面的练习中我们通过小写字母的ASCII值减32得到大下字母的ASCII值,其实C语言中还存在转换函数:

int tolower ( int c ); //将参数传进去的⼤写字⺟转⼩写 
int toupper ( int c ); //将参数传进去的⼩写字⺟转⼤写

有了转换函数,就可以直接使用 tolower() 函数:

#include <stdio.h>
#include <ctype.h>
int main ()
{
   int i = 0;
   char str[] = "Test String.\n";
   char c;
   while (str[i])
  {
      c = str[i];
      if (islower(c)) 
         c = toupper(c);
      putchar(c);
      i++;
   }
 return 0;
}

三、strlen()函数

strlen()函数是求字符串长度的,函数语法定义:

 size_t strlen ( const char * str );

字符串以 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符 个数 (不包

  含 '\0' )。

参数指向的字符串必须要以 '\0' 结束。

注意函数的返回值为 size_t ,是无符号的(易错 )

strlen的使 需要包含头文件(string.h)

#include <stdio.h>
#include <string.h>
int main()
{
   const char* str1 = "abcdef";
   const char* str2 = "bbb";
   if(strlen(str2)-strlen(str1)>0)//6-3
   {
     printf("str2>str1\n");
    } 
   else
   {
     printf("srt1>str2\n");
    }
   return 0;
}

strlen的模拟实现

我们也可以通过自己的方式来实现 strlen() 函数

方法1:

//计数器⽅式
int my_strlen(const char * str)
{
    int count = 0;
    assert(str);
    while(*str)
    {
      count++;
      str++;
     }
    return count;
}

方法2:

//不能创建临时变量计数器
int my_strlen(const char * str)
{
   assert(str);
   if(*str == '\0')
     return 0;
   else
   return 1+my_strlen(str+1);//采用递归的方式
}

方法3:

//指针-指针的⽅式
int my_strlen(char *s)
{
    assert(str);
    char *p = s;
    while(*p != ‘\0’ )
        p++;
    return p-s;//指针-指针的绝对值等于他们之间元素个数
}

四、strcpy()函数

strcpy()函数可以复制一个字符串到另外一个字符串中,函数语法定义:

char* strcpy(char * destination, const char * source );

Copies the C string pointed by source into the array pointed by destination, including the

   terminating null character (and stopping at that point).

源字符串必须以 '\0' 结束。

会将源字符串中的 '\0' 拷贝到目标空间。

标空间必须 足够大 ,以确保能存放源字符串。

标空间必须 可修改

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>

int main() {
	char arr1[20] = "hello word";
	char arr2[20] = { 0 };
	char *ret=strcpy(arr2, arr1);
	printf("%s\n", ret);
}

输出:

我们也可以通过自己的方式来实现strcpy()函数:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>

char* my_strcpy(char* dest, const char* source) {
	assert(dest != 0);
	assert(source != 0);//判断不为空指针
	char* c = dest;
	while (*dest++ = *source++) {
		;
	}
	return c;//返回起始地址
}

int main() {
	char arr1[20] = "hello word";
	char arr2[20] = { 0 };
	char* ret = my_strcpy(arr2, arr1);
	printf("%s\n", ret);
}

五、strcat()函数

strcat()是把一个字符串追加到另一个字符串后面,函数语法定义:

char * strcat ( char * destination, const char * source );

Appends a copy of the source string to the destination string. The terminating null character

in destination is overwritten by the first character of source, and a null-character is included

at the end of the new string formed by the concatenation of both in destination.

源字符串必须以 ' \0 ' 结束。

标字符串中也得有 ' \0 ' ,否则没办法知道追加从哪里开始。

标空间必须有足够的大,能容纳下源字符串的内容。

标空间必须可修改。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>

int main() {
	char arr1[20] = "hello ";
	char arr2[20] = "word";
    char * ret=strcat(arr1, arr2);
	printf("%s\n",ret);
}

我们也可以通过自己的方式来实现strcat()函数:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>

char* my_strcat(char* dest, const char* source) {
	assert(dest != NULL); 
	assert(source != NULL);
	char * ret = dest;
	while (*dest!= '\0')//先遍历到追加字符串的'\0'
		dest++;
	while (*dest++=*source++)//再拷贝
		;
	return ret;
}dest++

int main() {
	char arr1[20] = "hello ";
	char arr2[20] = "word";
	char *ret=my_strcat(arr1, arr2);
	printf("%s\n", ret);
}

六、strcmp()函数

strcmp()是比较两个字符串的,函数语法定义:

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

This function starts comparing the first character of each string. If they are equal to each

   other, it continues with the following pairs until the characters differ or until a terminating

   null-character is reached.

标准规定:

      ◦ 第⼀个字符串大于第⼆个字符串,则返回 大于0 的数字

      ◦ 第⼀个字符串等于第⼆个字符串,则返回 0

      ◦ 第⼀个字符串小于第⼆个字符串,则返回 小于0 的数字

      ◦ 那么如何判断两个字符串? 比较两个字符串中对应位置上字符 ASCII码值的大小

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>

int main() {
	char arr1[] = "abcdef";
	char arr2[] = "abq";//q
	int ret = strcmp(arr1, arr2);
	printf("%d", ret);
}

因为第三位c的ASCII值比q小,所以返回小于零的数字

我们也可以通过自己的方式来实现strcmp()函数:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>

int my_strcmp(const char* str1, const char* str2) {
	assert(str1 && str2);
	while (*str1 == *str2)
	{
		if (*str1 == '\0')
		return 0;
		str1++;
		str2++;
	}
	return *str1 - *str2;
}
int main() {
	char arr1[] = "abcdef";
	char arr2[] = "abq";
	int ret = my_strcmp(arr1, arr2);
	printf("%d", ret);
}

七、strncpy()函数

strncpy()函数与strcpy()函数类似,只不过限制了复制的个数。语法定义如下:

 char * strncpy ( char * destination, const char * source, size_t num );

Copies the first num characters of source to destination. If the end of the source C string

  (which is signaled by a null-character) is found before num characters have been copied,

   destination is padded with zeros until a total of num characters have been written to it.

拷贝 num 个字符从源字符串到目标空间。

如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边 追加0 ,直到 num 个。

#include<stdio.h>
#include<string.h>

int main() {
	char arr1[20] = "I love You";
	char arr2[20] = { 0 };
	strncpy(arr2, arr1, 6);
	printf("%s\n", arr2);
}

八、strncat()函数

strncat()函数与strcat()函数类似,只不过限制了连接个数,函数语法定义如下:

 char * strncat ( char * destination, const char * source, size_t num );

Appends the first num characters of source to destination, plus a terminating null-character. (将source指向字符串的前num个字符追加到destination指向的字符串末尾,再追加⼀个 \0 字 符)。

If the length of the C string in source is less than num, only the content up to the terminating       null-character is copied.(如果source 指向的字符串的长度小于num的时候,只会将字符串中到    \0 的内容追加到destination指向的字符串末尾)。

#include<stdio.h>
#include<string.h>

int main()
{
	char str1[20];
	char str2[20];
	strcpy(str1, "To be ");
	strcpy(str2, "or not to be");
	strncat(str1, str2, 6);
	printf("%s\n", str1);
	return 0;
}

九、strncmp()函数

strncmp()strcmp() 类似,只不过规定了最多比较的多少,函数语法定义:

int strncmp ( const char * str1, const char * str2, size_t num );

比较str1和str2的前num个字符,如果相等就继续往后比较,最多比较 num 个字⺟,如果提前发现不⼀样,就提前结束,大的字符所在的字符串⼤于另外⼀个。如果num个字符都相等,就是相等返回0.

十、strstr()函数

strstr()函数是在一个字符串查找另外一个字符串,函数语法定义:

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

Returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 is not part of str1.

(函数返回字符串str2在字符串str1中 第⼀次出现的位置 )。

The matching process does not include the terminating null-characters, but it stops there.(字符

串的比较匹配不包含 \0 字符,以 \0 作为结束标志)。

/* strstr example */
#include <stdio.h>
#include <string.h>
int main ()
{
   char str[] ="This is a simple string";
   char * pch;
   pch = strstr (str,"simple");
   strncpy (pch,"sample",6);
   printf("%s\n", str);
   return 0;
}

代码实现:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>

char* my_strstr(const char* str1, const char* str2) {
	char* s1 = NULL;
	char* s2 = NULL;
	const char* cur = str1;//比较的起始位置
	while (*cur)
	{
		s1 = cur;
		s2 = str2;
		while (*s1!='\0' &&*s2!='\0'&& *s1==*s2)//循环判断是否相等
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0') //比较结束
			return (char *)cur;
		cur++;//下一个
	}
	return NULL;//没有找到
}

int main() {
	char arr1[20] = "abbbcde";
	char arr2[20] = "bbc";
	//printf("%s",strstr(arr1, arr2));
	char* ret = my_strstr(arr1, arr2);
	printf("%s", ret);

}

十一、strtok()函数

strtok()函数是分隔字符串的,分隔符集合放在一个字符串中里。函数语法定义:

char * strtok ( char * str, const char * sep);

sep参数指向⼀个 字符串 ,定义了用作分隔符的字符集合

第⼀个参数指定⼀个字符串,它包含了0个或者多个由sep字符串中⼀个或者多个分隔符分割的标

  记。

strtok函数找到str中的下⼀个标记,并将其用  \0 结尾,返回⼀个指向这个标记的指针。(注:

  strtok函数会改变被操作的字符串,所以在使⽤strtok函数切分的字符串⼀般都是临时拷贝的内容

  并且可修改。)

strtok函数的第⼀个参数不为 NULL ,函数将找到str中第⼀个 标记 ,strtok函数将保存它在字符串

  中的位置。

strtok函数的第⼀个参数为 NULL ,函数将在同⼀个字符串中 被保存的位置开始 ,查找下⼀个标

  记。

如果字符串中不存在更多的标记,则返回 NULL 指针。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>

int main(){
     char arr[] = "192.168.6.111";
	 char* sep = ".";
	 char* str = NULL;
	for (str = strtok(arr, sep); str != NULL; str = strtok(NULL, sep))
		 {
		 printf("%s\n", str);
		}
	 return 0;
  }

十二、strerror()函数

strerror()函数可以把参数部分错误码对应的错误信息的字符串地址返回来。函数语法定义:

char * strerror ( int errnum );

在不同的系统和C语⾔标准库的实现中都规定了⼀些 错误码 ,⼀般是放在 errno.h 这个头文件中说明的,C语⾔程序启动的时候就会使用⼀个全⾯的变量errno来记录程序的当前错误码,只不过程序启动的时候errno是0,表示没有错误,当我们在使⽤标准库中的函数的时候发⽣了某种错误,就会讲对应的错误码,存放在errno中,而⼀个错误码的数字是整数很难理解是什么意思,所以每⼀个错误码都是有对应的 错误信息 的。strerror函数就可以将错误对应的 错误信息字符串的地址返回

我们来看看0~10的错误码信息:

#include <errno.h>
#include <string.h>
#include <stdio.h>

int main()
{
   int i = 0;
   for (i = 0; i <= 10; i++) {
        printf("%s\n", strerror(i));
     }
  return 0;
}

也可以了解⼀下perror函数,perror函数相当于⼀次将上述代码中的第9行完成了,直接将错误信息打印出来。perror函数打印完参数部分的字符串后,再打印⼀个冒号和⼀个空格,再打印错误信息。

#include <stdio.h>
#include <string.h>
#include <errno.h>
int main ()
 {
   FILE * pFile;
   pFile = fopen ("unexist.ent","r");
   if (pFile == NULL)
   perror("Error opening file unexist.ent");
   return 0;
 }


总结

上述文章讲了一些常见的字符函数和字符串函数,同时讲了一些它们的实现原理。希望对你有所帮助。

举报

相关推荐

0 条评论