编程语言 | C | 4. 字符、字符串以及内存函数

小时候幸福是一件很简答的事, 长大了简单是一件很幸福的事!

编程语言 | C | 4. 字符、字符串以及内存函数

在这里插入图片描述

4.1 字符串操作函数
4.1.1 求字符串长度(strlen)

函数原型

size_t strlen ( const char * str );

函数介绍

  • 1.字符串已经将 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包含 ‘\0’ );
  • 2.参数指向的字符串必须要以’\0’ 结束;
  • 3.注意函数的返回值为size_t,是无符号的。

strlen函数的模拟实现
<1> 采用循环 + 计数器

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

int my_strlen(const char*str) {
    assert(str != NULL);
    int count = 0;						//计数器
    while (*str != '\0') {
        count++;
        str++;
    }
    return count;
}
int main() {
    char string[] = "abcdef";  			//应将字符串放入一个字符型数组中
    int ret = 0;
    ret = my_strlen(string);
    printf("字符串长度为:%d\n", ret);
    system("pause");
    return 0;
}

<2> 采用递归的方式

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

int my_strlen(const char *str) {
    assert(str != NULL);
    if (*str == '\0') {
        return 0;
    }
    else {
        return 1 + strlen(str + 1);
    }
}
int main() {
    char string[] = "qwertyuiop";
    int ret = 0;
    ret = my_strlen(string);
    printf("字符串的长度为:%d\n", ret);
    system("pause");
    return 0;
}

<3> 采用指针 - 指针的方式

基本思想

  • 通过定义两个指针, 一个指向字符串的首段, 一个指向字符串的末尾, 然后通过字符串首尾两个指针相减, 就可以计算出中间隔了多少个元素, 即字符串的长度.
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

//因为字符串是不用变的,所以用const
int my_strlen(const char*str) {
    assert(str != NULL);
    //用一个指针来存放起始指针的位置, 要用const修饰,因为str就是一个const修饰的变量
    const char*start = str;	
    while (*str != '\0') {
        str++;
    }
    return str - start;
}

int main() {
    char string[] = "qwertyuiop";
    int ret = 0;
    ret = my_strlen(string);
    printf("字符串长度为:%d\n", ret);
    system("pause");
    return 0;
}
4.1.2 长度不受限制的字符串函数(strcpy、strcat、strcmp)

(1) strcpy (字符串拷贝)
函数原型

char* strcpy(char * destination, const char * source );
Return Value : destination is returned.

函数介绍

  • 1.源字符串必须以’\0’ 结束, 并且会将源字符串中的 ‘\0’ 拷贝到目标空间;
  • 2.目标空间必须足够大,以确保能存放源字符串, 并且目标空间必须可变;
  • 3.在复制或者追加字符串时, 不会执行溢出检查, 如果源字符串和目标字符串重叠, strcpy 的行为是未定义的.

strcpy函数的模拟实现

#include<stdio.h>
#include <assert.h>

char* my_strcpy(char* dest, const char* src) {
	int i;
	assert(src != NULL);
	assert(dest != NULL);
	for (i = 0; src[i] != '\0'; ++i) {
		dest[i] = src[i];
	}
	dest[i] = '\0';
	return dest;
}
int main() {
	char* p = "abcdef";
	char string[1024] = { 0 };
	my_strcpy(string, p);
	printf("%s\n", string);
	system("pause");
	return 0;
}

(2) strcat (字符串追加)
函数原型

char * strcat ( char * destination, const char * source );
Return Value : destination is returned.

函数介绍

  • 1.源字符串必须以 ‘\0’ 结尾;
  • 2.目标空间必须足够大, 能容纳下源字符串的内容;
  • 3.目标空间必须可修改;
  • 4 在追加字符串时, 它不会执行溢出检查, strcat的行为是未定义的.

strcat函数的模拟实现

#include <stdio.h>
#include <assert.h>
char* my_strcat(char* dest, const char* src) {
	int i;
	int j;
	assert(src != NULL);
	assert(dest != NULL);
	for (i = 0; dest[i] != '\0'; ++i);
	for (j = 0; src[j] != '\0'; ++i, ++j) {
		dest[i] = dest[j];
	}
	dest[i] = '\0';
	return dest;
}
int main() {
	char string1[1024] = "aaa";
	char string2[1024] = "bbb";
	my_strcat(string2, string1);
	printf("%s\n", string1);
	printf("%s\n", string2);
	system("pause");
	return 0;
}

(3) strcmp
函数原型

int strcmp ( const char * str1, const char * str2 );
Return Value: 第一个字符串大于第二个字符串,则返回大于0的数字;
			  第一个字符串等于第二个字符串,则返回0;
        	  第一个字符串小于第二个字符串,则返回小于0的数字.

函数介绍

  • 第一个字符串大于第二个字符串,则返回大于0的数字;
  • 第一个字符串等于第二个字符串,则返回0;
  • 第一个字符串小于第二个字符串,则返回小于0的数字.

strcmp函数的模拟实现

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

int my_strcmp(const char* str1, const char* str2) {
	assert(str1 != NULL);
	assert(str2 != NULL);
	int i;
	for (i = 0; str1[i] != '\0'&& str2[i] != '\0'; ++i) {
		if (str1[i] < str2[i]){
			return -1;
		}
		else{
			// 什么都不做,直接比较下一个字符
		}
	} 
	if (str1[i] < str2[i]) {
		return -1;
	}
	else if (str1[i] > str2[i]) {
		return 1;
	}
	else {
		return 0;
	}
}

int main() {
	char str1[1024] = "aaa";
	char str2[1024] = "bbb";
	//strcmp  o(n)=n
	int ret = my_strcmp(str1,str2);
	if (ret > 0) {
		printf("str1 > str2\n");
	}
	else if (ret < 0) {
		printf("str1 < str2\n");
	}
	else{ 
		printf("str1 == str2\n");
	}
	system("pause");
	return 0;
}
4.1.3 长度受限制的字符串函数(strncpy、strncat、strncmp)

(1) strncpy
函数原型

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

函数介绍

  • 1.拷贝num个字符从源字符串到目标字符串;
  • 2.如果源字符串的长度小于num, 则可拷贝源字符串后, 在目标字符串后边追加0, 直到num个.

(2) strncat
函数原型

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

函数介绍

  • 1.源字符串的初始字符覆盖了目标字符字符串最初的终止NULL字符;
  • 2.如果num大于源字符串的长度, 则使用源字符串的长度代替计数, 结果以NULL字符结束.

(3) strncmp
函数原型

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

函数介绍 (针对这两个字符串中前num个字符的比较)

  • 1.比较到出现在另外一个字符不一样, 或者一个字符结束, 或者num个字符全部比较完;
  • 2.如果第一个字符串大于第二个字符串的内容, 则返回大于0的数字;
  • 3.如果第一个字符串等于第二个字符窜的内容, 则返回0;
  • 4.如果第一个字符串小于第二个字符串的内容, 则返回小于0的数字.
4.1.4 字符串查找

(1) strstr
函数原型

char * strstr ( const char * str1, const char * str2);
return value: A pointer to the first occurrence in str1 of the entire sequence of
characters specified in str2, or a null pointer if the sequence is not present in str1.

函数介绍

  • 1.如果 str2 在 str1中, 则将返回一个指针或者句柄; 如果 str2 没有在 str1中, 则将返回一个空指针;
  • 2.在串中查找指定字符串的第一次出现。

strstr函数的模拟实现

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

char* Strstr(const char * str1,const char * str2) {
	assert(str1 != NULL);
	assert(str2 != NULL);
	if (*str2 == '\0') {
		return NULL;
	}
	// 黑指针功能是记录从哪个位置找字符串
	const char* black_ptr = str1;
	while (*black_ptr !='0') {
	// 红指针帮我们完成具体的字符串比较
		const char* red_ptr = black_ptr;
		const char* sub_ptr = str2;
		while (*red_ptr == *sub_ptr && *red_ptr != '\0'
			&& *sub_ptr != '\0') {
			++red_ptr;
			++sub_ptr;
		}
		if (*sub_ptr == '\0') {
			return black_ptr;
		}
		++black_ptr;
	}
	return NULL;
}

(2) strchr
函数原型

char * strchr(char * str, char/int c);
return value: Returns a pointer to the first occurrence of character in the 
C string str.

函数介绍

  • 1.在字符串str中寻找字符c第一次出现的位置, 并返回其位置(地址指针), 若失败则返回NULL;

strchr函数的模拟实现

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

const char* Strchr(const char* str,int character) {
	assert(str != NULL);
	while (*str++) {
		if (character == *str) {
			return str;
		}
	}
	return NULL;
}
int main () {
	const char* search_char;
	char str[1024];
	char character;
	gets(str);
	character = getchar();
	search_char = Strchr(str, character);
	puts(search_char);
	return 0;
}

(3) strtok
函数原型

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

函数介绍

  • 1.sep参数是个字符串,定义了用作分隔符的字符集合;
  • 2.第一个参数指定一个字符串, 它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记;
  • 3.strtok函数找到str中的下一个标记, 并将其用\0 结尾, 返回一个指向这个标记的指针 (注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改).
  • 4.strtok函数的第一个参数不为NULL, 函数将找到str中第一个标记, strtok函数将保存它在字符串中的位置.
  • 5.strtok函数的第一个参数为NULL, 函数将在同一个字符串中被保存的位置开始, 查找下一个标记。
  • 6.如果字符串中不存在更多的标记, 则返回NULL 指针.
4.1.5 字符串错误信息输出

strerror

函数原型

char * strerror ( int errnum );

函数介绍

  • 1.返回错误码, 所对应的错误信息.
4.2 字符分类函数

菜鸟教程: https://www.runoob.com/cprogramming/c-standard-library-ctype-h.html

4.2.1 iscntrl (任何控制字符)
描述
C 库函数 void iscntrl(int c) 检查所传的字符是否是控制字符。

声明
int iscntrl(int c);

参数
c -- 这是要检查的字符。

返回值
如果 c 是一个控制字符,则该函数返回非零值,否则返回 0。

实例
#include <stdio.h>
#include <ctype.h>

int main ()
{
   int i = 0, j = 0;
   char str1[] = "all \a about \t programming";
   char str2[] = "Runoob \n tutorials";
  
   /* 输出字符串直到控制字符 \a */
   while( !iscntrl(str1[i]) ) 
   {
      putchar(str1[i]);
      i++;
   }
  
   /* 输出字符串直到控制字符 \n */
   while( !iscntrl(str2[j]) ) 
   {
      putchar(str2[j]);
      j++;
   }
   
   return(0);
}

让我们编译并运行上面的程序,这将产生以下结果:

all Runoob 
4.2.2 isspace (空白字符)
描述
C 库函数 int isspace(int c) 检查所传的字符是否是空白字符。
标准的空白字符包括:

' '     (0x20)    space (SPC) 空格符
'\t'    (0x09)    horizontal tab (TAB) 水平制表符    
'\n'    (0x0a)    newline (LF) 换行符
'\v'    (0x0b)    vertical tab (VT) 垂直制表符
'\f'    (0x0c)    feed (FF) 换页符
'\r'    (0x0d)    carriage return (CR) 回车符

声明
int isspace(int c);

参数
c -- 这是要检查的字符。

返回值
如果 c 是一个空白字符,则该函数返回非零值(true),否则返回 0(false)。

实例
下面的实例演示了 isspace() 函数的用法。

#include <stdio.h>
#include <ctype.h>

int main()
{
   int var1 = 't';
   int var2 = '1';
   int var3 = ' ';

   if( isspace(var1) )
   {
       printf("var1 = |%c| 是空白字符\n", var1 );
   }
   else
   {
       printf("var1 = |%c| 不是空白字符\n", var1 );
   }
   if( isspace(var2) )
   {
       printf("var2 = |%c| 是空白字符\n", var2 );
   }
   else
   {
       printf("var2 = |%c| 不是空白字符\n", var2 );
   }
   if( isspace(var3) )
   {
       printf("var3 = |%c| 是空白字符\n", var3 );
   }
   else
   {
       printf("var3 = |%c| 不是空白字符\n", var3 );
   }
   
   return(0);
}
让我们编译并运行上面的程序,这将产生以下结果:

var1 = |t| 不是空白字符
var2 = |1| 不是空白字符
var3 = | | 是空白字符
4.2.3 isdigit (十进制数字0-9)
描述
C 库函数 int isdigit(int c) 检查所传的字符是否是十进制数字字符。

十进制数字是:0 1 2 3 4 5 6 7 8 9

声明
下面是 isdigit() 函数的声明。

int isdigit(int c);
参数
c -- 这是要检查的字符。
返回值
如果 c 是一个数字,则该函数返回非零值,否则返回 0。

实例
下面的实例演示了 isdigit() 函数的用法。

#include <stdio.h>
#include <ctype.h>

int main()
{
   int var1 = 'h';
   int var2 = '2';
    
   if( isdigit(var1) )
   {
      printf("var1 = |%c| 是一个数字\n", var1 );
   }
   else
   {
      printf("var1 = |%c| 不是一个数字\n", var1 );
   }
   if( isdigit(var2) )
   {
      printf("var2 = |%c| 是一个数字\n", var2 );
   }
   else
   {
      printf("var2 = |%c| 不是一个数字\n", var2 );
   }
  
   return(0);
}
让我们编译并运行上面的程序,这将产生以下结果:

var1 = |h| 不是一个数字
var2 = |2| 是一个数字
4.2.4 isxdigit (十六进制数字, 包括十进制数字, 小写字母a-f, 大写字母A-F)
描述
C 库函数 int isxdigit(int c) 检查所传的字符是否是十六进制数字。

int isxdigit(int c) 参数 c 是单个字符。

十六进制一般用数字 09 和字母 A 到 F(或 a~f)表示,其中 A~F 表示 10~15: 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F。

声明
下面是 isxdigit() 函数的声明。

int isxdigit(int c);
参数
c -- 这是要检查的字符。
返回值
如果 c 是一个十六进制数字,则该函数返回非零的整数值,否则返回 0。

实例
下面的实例演示了 isxdigit() 函数的用法。

实例
#include <ctype.h>
#include <stdio.h>
 
int main() {
   char c = '5';
   int result;
 
   // 传入字符
   result = isxdigit(c); // result 返回非 0
   printf("%c 传入到 isxdigit() 函数结果为: %d", c, isxdigit(c));
   printf("\n");  // 换行
   c = 'M';
 
   // 非十六进制数作为参数
   result = isxdigit(c); // result 为 0
 
   printf("%c 传入到 isxdigit() 函数结果为: %d", c, isxdigit(c));
 
   return 0;
}
让我们编译并运行上面的程序,这将产生以下结果:

5 传入到 isxdigit() 函数结果为: 1
M 传入到 isxdigit() 函数结果为: 0
4.2.5 islower (小写字母a-z)
描述
C 库函数 int islower(int c) 检查所传的字符是否是小写字母。

声明
下面是 islower() 函数的声明。

int islower(int c);
参数
c -- 这是要检查的字符。
返回值
如果 c 是一个小写字母,则该函数返回非零值(true),否则返回 0(false)。

实例
下面的实例演示了 islower() 函数的用法。

#include <stdio.h>
#include <ctype.h>

int main()
{
   int var1 = 'Q';
   int var2 = 'q';
   int var3 = '3';
    
   if( islower(var1) )
   {
       printf("var1 = |%c| 是小写字母\n", var1 );
   }
   else
   {
      printf("var1 = |%c| 不是小写字母\n", var1 );
   }
   if( islower(var2) )
   {
       printf("var2 = |%c| 是小写字母\n", var2 );
   }
   else
   {
      printf("var2 = |%c| 不是小写字母\n", var2 );
   }
   if( islower(var3) )
   {
       printf("var3 = |%c| 是小写字母\n", var3 );
   }
   else
   {
      printf("var3 = |%c| 不是小写字母\n", var3 );
   }
   
   return(0);
}
让我们编译并运行上面的程序,这将产生以下结果:

var1 = |Q| 不是小写字母
var2 = |q| 是小写字母
var3 = |3| 不是小写字母
4.2.6 isupper (大写字母A-Z)
描述
C 库函数 int isupper(int c) 检查所传的字符是否是大写字母。

声明
下面是 isupper() 函数的声明。

int isupper(int c);
参数
c -- 这是要检查的字符。
返回值
如果 c 是一个大写字母,则该函数返回非零值(true),否则返回 0(false)。

实例
下面的实例演示了 isupper() 函数的用法。

#include <stdio.h>
#include <ctype.h>

int main()
{
   int var1 = 'M';
   int var2 = 'm';
   int var3 = '3';
    
   if( isupper(var1) )
   {
      printf("var1 = |%c| 是大写字母\n", var1 );
   }
   else
   {
      printf("var1 = |%c| 不是大写字母\n", var1 );
   }
   if( isupper(var2) )
   {
      printf("var2 = |%c| 是大写字母\n", var2 );
   }
   else
   {
      printf("var2 = |%c| 不是大写字母\n", var2 );
   }   
   if( isupper(var3) )
   {
      printf("var3 = |%c| 是大写字母\n", var3 );
   }
   else
   {
      printf("var3 = |%c| 不是大写字母\n", var3 );
   }
   
   return(0);
}
让我们编译并运行上面的程序,这将产生以下结果:

var1 = |M| 是大写字母
var2 = |m| 不是大写字母
var3 = |3| 不是大写字母
4.2.7 isalpha (字母a-z或者字母A-Z)
描述
C 库函数 void isalpha(int c) 检查所传的字符是否是字母。

声明
下面是 isalpha() 函数的声明。

int isalpha(int c);
参数
c -- 这是要检查的字符。
返回值
如果 c 是一个字母,则该函数返回非零值,否则返回 0。

实例
下面的实例演示了 isalpha() 函数的用法。

#include <stdio.h>
#include <ctype.h>

int main()
{
   int var1 = 'd';
   int var2 = '2';
   int var3 = '\t';
   int var4 = ' ';
    
   if( isalpha(var1) )
   {
      printf("var1 = |%c| 是一个字母\n", var1 );
   }
   else
   {
      printf("var1 = |%c| 不是一个字母\n", var1 );
   }
   if( isalpha(var2) )
   {
      printf("var2 = |%c| 是一个字母\n", var2 );
   }
   else
   {
      printf("var2 = |%c| 不是一个字母\n", var2 );
   }
   if( isalpha(var3) )
   {
      printf("var3 = |%c| 是一个字母\n", var3 );
   }
   else
   {
      printf("var3 = |%c| 不是一个字母\n", var3 );
   }
   if( isalpha(var4) )
   {
      printf("var4 = |%c| 是一个字母\n", var4 );
   }
   else
   {
      printf("var4 = |%c| 不是一个字母\n", var4 );
   }
   
   return(0);
}
让我们编译并运行上面的程序,这将产生以下结果:

var1 = |d| 是一个字母
var2 = |2| 不是一个字母
var3 = | | 不是一个字母
var4 = | | 不是一个字母
4.2.9 isalnum (字母和者数字, a-z, A-Z, 0-9)
描述
C 库函数 void isalnum(int c) 检查所传的字符是否是字母和数字。

声明
下面是 isalnum() 函数的声明。

int isalnum(int c);
参数
c -- 这是要检查的字符。
返回值
如果 c 是一个数字或一个字母,则该函数返回非零值,否则返回 0。

实例
下面的实例演示了 isalnum() 函数的用法。

#include <stdio.h>
#include <ctype.h>

int main()
{
   int var1 = 'd';
   int var2 = '2';
   int var3 = '\t';
   int var4 = ' ';
    
   if( isalnum(var1) )
   {
      printf("var1 = |%c| 是字母数字\n", var1 );
   }
   else
   {
      printf("var1 = |%c| 不是字母数字\n", var1 );
   }
   if( isalnum(var2) )
   {
      printf("var2 = |%c| 是字母数字\n", var2 );
   }
   else
   {
      printf("var2 = |%c| 不是字母数字\n", var2 );
   }
   if( isalnum(var3) )
   {
      printf("var3 = |%c| 是字母数字\n", var3 );
   }
   else
   {
      printf("var3 = |%c| 不是字母数字\n", var3 );
   }
   if( isalnum(var4) )
   {
      printf("var4 = |%c| 是字母数字\n", var4 );
   }
   else
   {
      printf("var4 = |%c| 不是字母数字\n", var4 );
   }
    
   return(0);
}
让我们编译并运行上面的程序,这将产生以下结果:

var1 = |d| 是字母数字
var2 = |2| 是字母数字
var3 = | | 不是字母数字
var4 = | | 不是字母数字
4.2.10 ispunct (标点符号, 任何不属于数字或者字母的图形字符, 可打印)
描述
C 库函数 int ispunct(int c) 检查所传的字符是否是标点符号字符。标点符号字符可以是非字母数字(正如 isalnum 中的一样)的任意图形字符(正如 isgraph 中的一样)。

声明
下面是 ispunct() 函数的声明。

int ispunct(int c);
参数
c -- 这是要检查的字符。
返回值
如果 c 是一个标点符号字符,则该函数返回非零值(true),否则返回 0(false)。

实例
下面的实例演示了 ispunct() 函数的用法。

#include <stdio.h>
#include <ctype.h>

int main()
{
   int var1 = 't';
   int var2 = '1';
   int var3 = '/';
   int var4 = ' ';

   if( ispunct(var1) )
   {
       printf("var1 = |%c| 是标点符号字符\n", var1 );
   }
   else
   {
       printf("var1 = |%c| 不是标点符号字符\n", var1 );
   }
   if( ispunct(var2) )
   {
       printf("var2 = |%c| 是标点符号字符\n", var2 );
   }
   else
   {
       printf("var2 = |%c| 不是标点符号字符\n", var2 );
   }
   if( ispunct(var3) )
   {
       printf("var3 = |%c| 是标点符号字符\n", var3 );
   }
   else
   {
       printf("var3 = |%c| 不是标点符号字符\n", var3 );
   }
   if( ispunct(var4) )
   {
       printf("var4 = |%c| 是标点符号字符\n", var4 );
   }
   else
   {
       printf("var4 = |%c| 不是标点符号字符\n", var4 );
   }
   
   return(0);
}  
让我们编译并运行上面的程序,这将产生以下结果:

var1 = |t| 不是标点符号字符
var2 = |1| 不是标点符号字符
var3 = |/| 是标点符号字符
var4 = | | 不是标点符号字符
4.2.11isgraph (任何图形字符)
描述
C 库函数 int isgraph(int c) 检查所传的字符是否有图形表示法。

带有图形表示法的字符是除了空白字符(比如 ' ')以外的所有可打印的字符。

声明
下面是 isgraph() 函数的声明。

int isgraph(int c);
参数
c -- 这是要检查的字符。
返回值
如果 c 有图形表示法,则该函数返回非零值,否则返回 0。

实例
下面的实例演示了 isgraph() 函数的用法。

实例
#include <stdio.h>
#include <ctype.h>
 
int main()
{
   int var1 = '3';
   int var2 = 'm';
   int var3 = ' ';
    
   if( isgraph(var1) )
   {
       printf("var1 = |%c| 是可打印的\n", var1 );
   }
   else
   {
      printf("var1 = |%c| 是不可打印的\n", var1 );
   }
   if( isgraph(var2) )
   {
       printf("var2 = |%c| 是可打印的\n", var2 );
   }
   else
   {
      printf("var2 = |%c| 是不可打印的\n", var2 );
   }
   if( isgraph(var3) )
   {
       printf("var3 = |%c| 是可打印的\n", var3 );
   }
   else
   {
      printf("var3 = |%c| 是不可打印的\n", var3 );
   }
   
   return(0);
}
让我们编译并运行上面的程序,这将产生以下结果:

var1 = |3| 是可打印的
var2 = |m| 是可打印的
var3 = | | 是不可打印的
以下实例打印所有图形字符:

实例
#include <stdio.h>
#include <ctype.h>
int main()
{
    int i;
    printf("C 语言中所有图形字符: \n");
    for (i=0;i<=127;++i)
    {
        if (isgraph(i)!=0)
            printf("%c ",i);
    }
    return 0;
}
让我们编译并运行上面的程序,这将产生以下结果:

C 语言中所有图形字符: 
! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~
4.2.12 isprint (任何打印字符, 包括图形字符和空白字符)
描述
C 库函数 int isprint(int c) 检查所传的字符是否是可打印的。可打印字符是非控制字符的字符。

声明
下面是 isprint() 函数的声明。

int isprint(int c);
参数
c -- 这是要检查的字符。
返回值
如果 c 是一个可打印的字符,则该函数返回非零值(true),否则返回 0(false)。

实例
下面的实例演示了 isprint() 函数的用法。

#include <stdio.h>
#include <ctype.h>

int main()
{
   int var1 = 'k';
   int var2 = '8';
   int var3 = '\t';
   int var4 = ' ';
    
   if( isprint(var1) )
   {
      printf("var1 = |%c| 是可打印的\n", var1 );
   }
   else
   {
      printf("var1 = |%c| 是不可打印的\n", var1 );
   }
   if( isprint(var2) )
   {
      printf("var2 = |%c| 是可打印的\n", var2 );
   }
   else
   {
      printf("var2 = |%c| 是不可打印的\n", var2 );
   }
   if( isprint(var3) )
   {
      printf("var3 = |%c| 是可打印的\n", var3 );
   }
   else
   {
      printf("var3 = |%c| 是不可打印的\n", var3 );
   }
   if( isprint(var4) )
   {
      printf("var4 = |%c| 是可打印的\n", var4 );
   }
   else
   {
      printf("var4 = |%c| 是不可打印的\n", var4 );
   }
   
   return(0);
}   
让我们编译并运行上面的程序,这将产生以下结果:

var1 = |k| 是可打印的
var2 = |8| 是可打印的
var3 = |    | 是不可打印的
var4 = | | 是可打印的
4.3 字符转换
4.3.1 int tolower ( int c );
描述
C 库函数 int tolower(int c) 把给定的字母转换为小写字母。

声明
下面是 tolower() 函数的声明。

int tolower(int c);
参数
c -- 这是要被转换为小写的字母。
返回值
如果 c 有相对应的小写字母,则该函数返回 c 的小写字母,否则 c 保持不变。返回值是一个可被隐式转换为 char 类型的 int 值。

实例
下面的实例演示了 tolower() 函数的用法。

实例
#include <stdio.h>
#include <ctype.h>
 
int main()
{
   int i = 0;
   char c;
   char str[] = "RUNOOB";
 
   while( str[i] ) 
   {
      putchar(tolower(str[i]));
      i++;
   }
 
   return(0);
}
让我们编译并运行上面的程序,这将产生以下结果:

runoob
4.3.2 int toupper ( int c );
描述
C 库函数 int toupper(int c) 把小写字母转换为大写字母。

声明
下面是 toupper() 函数的声明。

int toupper(int c);
参数
c -- 这是要被转换为大写的字母。
返回值
如果 c 有相对应的大写字母,则该函数返回 c 的大写字母,否则 c 保持不变。返回值是一个可被隐式转换为 char 类型的 int 值。

实例
下面的实例演示了 toupper() 函数的用法。

#include <stdio.h>
#include <ctype.h>

int main()
{
   int i = 0;
   char c;
   char str[] = "runoob";
   
   while(str[i])
   {
      putchar (toupper(str[i]));
      i++;
   }
   
  return(0);
}
让我们编译并运行上面的程序,这将产生以下结果:

RUNOOB
4.4 内存操作函数
4.4.1 memcpy
描述
C 库函数 void *memcpy(void *str1, const void *str2, size_t n) 从
存储区 str2 复制 n 个字节到存储区 str1。

声明
下面是 memcpy() 函数的声明。

void *memcpy(void *str1, const void *str2, size_t n)
参数
str1 -- 指向用于存储复制内容的目标数组,类型强制转换为 void* 指针。
str2 -- 指向要复制的数据源,类型强制转换为 void* 指针。
n -- 要被复制的字节数。
返回值
该函数返回一个指向目标存储区 str1 的指针。

实例
下面的实例演示了 memcpy() 函数的用法。

实例
// 将字符串复制到数组 dest 中
#include <stdio.h>
#include <string.h>
 
int main ()
{
   const char src[50] = "http://www.runoob.com";
   char dest[50];
 
   memcpy(dest, src, strlen(src)+1);
   printf("dest = %s\n", dest);
   
   return(0);
}
让我们编译并运行上面的程序,这将产生以下结果:

dest = http://www.runoob.com
将 s 中第 11 个字符开始的 6个连续字符复制到 d 中:

实例
#include <stdio.h>
#include<string.h>
 
int main()
 
{
  char *s="http://www.runoob.com";
  char d[20];
  memcpy(d, s+11, 6);// 从第 11 个字符(r)开始复制,连续复制 6 个字符(runoob)
  // 或者 memcpy(d, s+11*sizeof(char), 6*sizeof(char));
  d[6]='\0';
  printf("%s", d);
  return 0;
}
让我们编译并运行上面的程序,这将产生以下结果:

runoob
覆盖原有部分数据:

实例
#include<stdio.h>
#include<string.h>
 
int main(void)
{
  char src[] = "***";
  char dest[] = "abcdefg";
  printf("使用 memcpy 前: %s\n", dest);
  memcpy(dest, src, strlen(src));
  printf("使用 memcpy 后: %s\n", dest);
  return 0;
}
让我们编译并运行上面的程序,这将产生以下结果:

使用 memcpy 前: abcdefg
使用 memcpy 后: ***defg
4.4.2 memmove
描述
C 库函数 void *memmove(void *str1, const void *str2, size_t n) 从 str2 复制 
n 个字符到 str1,但是在重叠内存块这方面,memmove() 是比 memcpy() 更安全的方法。
如果目标区域和源区域有重叠的话,memmove() 能够保证源串在被覆盖之前将重叠区域的字节
拷贝到目标区域中,复制后源区域的内容会被更改。如果目标区域与源区域没有重叠,则和
 memcpy() 函数功能相同。

声明
下面是 memmove() 函数的声明。

void *memmove(void *str1, const void *str2, size_t n)
参数
str1 -- 指向用于存储复制内容的目标数组,类型强制转换为 void* 指针。
str2 -- 指向要复制的数据源,类型强制转换为 void* 指针。
n -- 要被复制的字节数。
返回值
该函数返回一个指向目标存储区 str1 的指针。

实例
下面的实例演示了 memmove() 函数的用法。

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

int main ()
{
   const char dest[] = "oldstring";
   const char src[]  = "newstring";

   printf("Before memmove dest = %s, src = %s\n", dest, src);
   memmove(dest, src, 9);
   printf("After memmove dest = %s, src = %s\n", dest, src);

   return(0);
}
让我们编译并运行上面的程序,这将产生以下结果:

Before memmove dest = oldstring, src = newstring
After memmove dest = newstring, src = newstring
4.4.3 memset
描述
C 库函数 void *memset(void *str, int c, size_t n) 复制字符 c(一个无符号字符)
到参数 str 所指向的字符串的前 n 个字符。

声明
下面是 memset() 函数的声明。

void *memset(void *str, int c, size_t n)
参数
str -- 指向要填充的内存块。
c -- 要被设置的值。该值以 int 形式传递,但是函数在填充内存块时是使用该值的无符号字符形式。
n -- 要被设置为该值的字符数。
返回值
该值返回一个指向存储区 str 的指针。

实例
下面的实例演示了 memset() 函数的用法。

实例
#include <stdio.h>
#include <string.h>
 
int main ()
{
   char str[50];
 
   strcpy(str,"This is string.h library function");
   puts(str);
 
   memset(str,'$',7);
   puts(str);
   
   return(0);
}
让我们编译并运行上面的程序,这将产生以下结果:

This is string.h library function
$$$$$$$ string.h library function
4.4.4 memcmp
描述
C 库函数 int memcmp(const void *str1, const void *str2, size_t n)) 把
存储区 str1 和存储区 str2 的前 n 个字节进行比较。

声明
下面是 memcmp() 函数的声明。

int memcmp(const void *str1, const void *str2, size_t n)
参数
str1 -- 指向内存块的指针。
str2 -- 指向内存块的指针。
n -- 要被比较的字节数。
返回值
如果返回值 < 0,则表示 str1 小于 str2。
如果返回值 > 0,则表示 str1 大于 str2。
如果返回值 = 0,则表示 str1 等于 str2。
实例
下面的实例演示了 memcmp() 函数的用法。

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

int main ()
{
   char str1[15];
   char str2[15];
   int ret;

   memcpy(str1, "abcdef", 6);
   memcpy(str2, "ABCDEF", 6);

   ret = memcmp(str1, str2, 5);

   if(ret > 0)
   {
      printf("str2 小于 str1");
   }
   else if(ret < 0)
   {
      printf("str1 小于 str2");
   }
   else
   {
      printf("str1 等于 str2");
   }
   
   return(0);
}
让我们编译并运行上面的程序,这将产生以下结果:

str2 小于 str1
4.4.5 memchr
描述
C 库函数 void *memchr(const void *str, int c, size_t n) 在参数 str 所
指向的字符串的前 n 个字节中搜索第一次出现字符 c(一个无符号字符)的位置。

声明
下面是 memchr() 函数的声明。

void *memchr(const void *str, int c, size_t n)
参数
str -- 指向要执行搜索的内存块。
c --int 形式传递的值,但是函数在每次字节搜索时是使用该值的无符号字符形式。
n -- 要被分析的字节数。
返回值
该函数返回一个指向匹配字节的指针,如果在给定的内存区域未出现字符,则返回 NULL。

实例
下面的实例演示了 memchr() 函数的用法。

实例
#include <stdio.h>
#include <string.h>
 
int main ()
{
   const char str[] = "http://www.runoob.com";
   const char ch = '.';
   char *ret;
 
   ret = (char*)memchr(str, ch, strlen(str));
 
   printf("|%c| 之后的字符串是 - |%s|\n", ch, ret);
 
   return(0);
}
让我们编译并运行上面的程序,这将产生以下结果:

|.| 之后的字符串是 - |.runoob.com|
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值