C语言学习笔记:19_数组-字符数组与字符串(常用字符串函数)

/*
 * 19_数组-字符数组与字符串.c
 *
 *  Created on: 2015年7月7日
 *      Author: zhong
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/**
 *一:字符数组:就是存放字符的char[]数组
 *  由于c语言中没有像java,C#中的String(字符串),只有存放字符 的字符型数组当字符串使用(java中的String类也是对字符数组进行封闭的)。
 *
 *二: 字符数组的定义:
 * 	 	char c[5];
 * 		c[0]='i'; c[2]='a'; //给数组元素赋值
 * 		由于字符型 数据是以整数形式存放(AscII代码),所以也可以定义int型的数组存放字符。 int c[10]; c[0]='i';
 *三: 字符数组的初始化:
 * 	 	char c[5]={'a','b','c','d','e'}; //和int数组一样初始化
 * 	 	char c[5]={'a','b','c'}; //当初始化数组中的一部分元素时,剩下没有初始化的元素被系统初始化为'\0'
 * 	 	char c[]={'a','b','c','d','e'}; //当被始全部时,前面[]中的长度可以不写
 * 	 	char c[];//如果定义数组时不初始化,哪么各元素的值是不可预料的。
 *
 *		char c[4][5]={{},{},{},{}}; //也可以定义一个二维字符数组并初始化值
 *
 *四:字符数组元素的引用:和其它数组一样,使用[下标]获得某个元素的值。
 *五:字符串和字符串结束标志:
 * 		在c语言中,是将字符串作为字符数组来处理的。
 * 		字符串结束标志:以字符‘\0’作为结束标志。 如字符数组中存放n个字符,前面9个字符都不普通字符,第10个字符是'\0',
 * 				  则认为数组中有一个字符串,其有效字符为9个。也就是说,在遇到字符'\0'时,表示字符串结束把厕所字符组成一个字符串。
 * 				 c语言用字符数组存储字符串常量时,会自动加一个'\0'作为结束符。
 * 		有了字符串结束标志,在程序中就可以检测'\0'的位置断定字符串是否结束。
 *
 * 六:用字符串形式给字符数组初始化:
 * 		char c[]={"I am Student"};
 * 		char c[]="I am Student";//可以省略{}
 *		要注意的时,这时字符数组的长度不是可见的字符个数12(加空格),而是13,因为系统会自动在't'后面添加 '\0'表示字符串的结束。
 *		char c[10]="abcd"; //后面没在字符的六个下标元素全部被初始化为'\0';
 *
 *	 注意:如果不是采用字符串形式给字符数组赋值,系统不会后面添加'\0';
 *	 	如 char c[5]={'a','b','c','d','e'}; //它的长度只有5
 *	 	  可以手动为其加上'\0'字符串结束标志,以便使用 char c[]={'a','b','c','d','e','\0'};
 *
 *	  由于'\0'作为字符串结束标志,当系统遇到'\0'时,停止了对字符串的输出
 *	  如char c[6]={'N','W','K','\0','a','b'}; //output: NWK        '\0'后面的字符不会再输出 了
 *
 * 七:字符数组的输入与输出:
 *	 输入:只输出第一个'\0'之前的字符
 *		printf("%c", arr[i]); //每个字符每个字符输出,使用%c+数组下标
 *		printf("%s\n",arr); //整个字符串一次输出, 用%s+字符数组名称
 *	输入:
 *		char c[6];
 *		scantf("%c",arr[i]);//一个个字符输入 %c+元素下标地址  要用&取得内存地址
 *		scanf("%s",c);  //直接输入一个字符串给字符数组赋值  %s+数组名  :因为数组名代表数组的起始地址,所以不用加&
 *
 *	  注意: 当输入带空格,只会将空格之前的字符传到数组中,数组后面的元素全部为'\0';
 *	  	如 char c[5];
 *	  	  scanf("%s",c);
 *	  	  当你输入:i am no  回车后
 *	  	   c字符数组元素如下:{'i','\0','\0','\0','\0'} //只获取到一个字符
 *
 *	由于数组名称代表数组起始地址,所以可以直接输出数组名查看数组内存的起始地址
 *		char c[6];
 printf("%x",c);//28ff30 以十六进制形式打印数组名

 八:字符串处理函数
 puts(字符数组名); 输出字符中的函数-将一个字符串(以'\0'结束的字符序列)输出一终端,可以包含转义字符
 	 	 	 因为puts()函数是在<stdio.h>头文件中声名的,所以要导入这个头文件

 gets(字符数组)--输入字符串的函数:从终端输入一个字符串到字符数组中,并得返回一个函数值,这个函数值是字符数组的起始地址
 	 	 	 因为gets()函数是在<stdio.h>头文件中声名的,所以要导入这个头文件

 strcat(数组1,数组2)-- 字符串连接函数,其作用是把两个字符数组中的字符串连接起,将数组2中字符接到数组1字串后面。 并返回数组1的内存地址
       	   	   因为strcat(数组1,数组2)函数声名是在头文件 string.h里面的,所以要#include <string.h>

 strcpy(字符数组1,字符串2)  字符串复制函数:作用是将字符串2复制到字符数组1中去。
	 	strcat(数组1,数组2)函数声名是在头文件 string.h里面的,所以要#include <string.h>

strcmp(字符串1,字符串2); 字符串函数比较函数, 要#include <string.h>

strlwr(字符串)  返回字符串的小写字母形式
strupr(字符串) 返回字符串的大写字母形式
		 * 函数声名都是在string.h里面

strlen(字符数组) 返回字符串的长度,是字符串实际的长度(不包含'\0'在内),不是数组的长度
	 *函数声名都是在string.h里面

使用方法都在下面clib_string_function_xxx()函数中。
更多的字符串处理方法,可以查看头文件 string.h里面对字符串处理函数进行了声名
 *
 */
//封闭打印数组的函数
void printf_char_array(char arr[], int len) {
	int i;
	for (i = 0; i < len; i++) {
		printf("%c", arr[i]); //每个字符每个字符输出,使用%c+数组下标
	}
	printf("\n");
}
void printf_char_array_2(char arr[]) {
	printf("%s\n", arr); //整个字符串一次输出, 用%s+字符数组名称
}

void printf_string() {
	char c[6] = { 'N', 'W', 'K', '\0', 'a', 'b' };
	printf_char_array(c, 4);
}

void scantf_string() {
	char c[6];
	int i;
	for (i = 0; i < 6; i++) {
		scanf("%c", &c[i]); //一个个字符输入 %c+元素下标地址  要用&取得内存地址
	}
	scanf("%s", c); //直接输入一个字符串给字符数组赋值  %s+数组名  :因为数组名代表数组的起始地址,所以不用加&
	printf("%s", c);
}

//-----------------c函数库中提供的字符串处理函数------------------------------

void clib_string_function_puts() {
//-------puts(字符数组名); 输出字符中的函数-将一个字符串(以'\0'结束的字符序列)输出一终端,可以包含转义字符
	//因为puts()函数是在<stdio.h>头文件中声名的,所以要导入这个头文件

//	char str[]="nwk nwk nwk nwk"; //以字符串赋值的数组,系统自动添加'\0'结束,输出没问题 :nwk nwk nwk nwk
//	char str[]={'a','b'}; //这个是普通的字符数组,并不以'\0'结尾 所以输出时会有问题:abH?(
	char str[] = { 'a', 'b', '\0' }; //手动为字符数组添加'\0'结束标记,这样输出才不会有问题:ab
	puts(str);
}

void clib_string_function_gets() {
//-----gets(字符数组)--输入字符串的函数:从终端输入一个字符串到字符数组中,并得返回一个函数值,这个函数值是字符数组的起始地址
	//因为gets()函数是在<stdio.h>头文件中声名的,所以要导入这个头文件

	char string[20];
	int p = gets(string); //从键盘输入:i am boy 系统会自动将字符赋值给string数组
	//注意,由于系统会将字符赋值给数组,而数组又是固定长度的,所以输入字符不能超过数组长度-1;
	//为什么只能输入数组长度-1个字符呢,因为系统默认会给数组加上'\0'结束标记,占用了一个元素
	puts(string); //将刚刚输入的内容打印:i am boy
	printf("\n这是数组的内存地址%d\n", p);
}
void clib_string_function_strcat() {
//---strcat(数组1,数组2)-- 字符串连接函数,其作用是把两个字符数组中的字符串连接起,将数组2中字符接到数组1字串后面。 并返回数组1的内存地址
	//strcat(数组1,数组2)函数声名是在头文件 string.h里面的,所以要#include <string.h>

	char str1[] = "zhong ";
	char str2[30] = "nwk";

	//输出连接后的字符
	strcat(str1, str2);
	puts(str1); //因为将str2放到了str1后了,所以现在可以直接打印str1得到连接后的字符串:zhong nwk
	/*注意:按理来说,因为将str2连接到str1中,所以str1的长度要足够大才行的,但是现在我的str1只能刚刚装下str1的字符
	 但是程序也没有报错,正常运行????????
	 */

//	puts(strcat(str1, str2)); //直接打印也行
//	printf("%s\n", strcat(str1, str2)); //zhong nwk
}
void clib_string_function_strcpy_or_strncpy() {
	/*strcpy(字符数组1,字符串2)  字符串复制函数:作用是将字符串2复制到字符数组1中去。
	 	strcat(数组1,数组2)函数声名是在头文件 string.h里面的,所以要#include <string.h>
	 */

//	char str[10]="nwk"; //如果str字符数组里面有内容,复制的时候会复盖掉
	char str[10]; //数组长度必须足够大,以便装下str2里面的所有字符串,否则运行出错
	char str2[]="NWKKKK";
	strcpy(str,str2);
//	strncpy(str,str2,3);  这个函数的作用和上面哪个差不多,只是可以指定将str2的前n个字符复制到str中。
//	strcpy(str,"NWK"); 被复制的内容也可以直接是字符串
	puts(str);
}

void clib_string_function_strcmp() {

	/*
	 * strcmp(字符串1,字符串2); 字符串函数比较函数, 要#include <string.h>
	 *
	 * 比较后返回的结果:
	 * 		如果字符串1=字符串2,则函数值为0,
	 * 		如果字符串1>字符串2,则函数值为一个正整个数
	 * 		如果字符串1<字符串2,则函数值为一个负整数
	 */

	//int result=strcmp("123","134"); //返回-1
			//如果全部字符相同,则认为两个字符串相等,返回0
			//若出现不相同的字符,则以第1对不相同的字符的结果为准: 如123,134  第2个字符2和3不相等,因为2<3,所以返回一个负数
	int result=strcmp("abc","acd");  //返回-1
			//如果是字符,两个字符比较是按照字典的先后顺序,后面的为大, 比如上面: b<c 所以返回-1

	printf("%d\n",result);

	char str1[]="123";
	char str2[]="123";
	if(strcmp(str1,str2)==0){ //因为两字符串相等,返回0,所以0==0 为真,
		printf("yes\n");
	}
}

void clib_string_function_strlen(){
	/**
	 *strlen(字符数组) 返回字符串的长度,是字符串实际的长度(不包含'\0'在内),不是数组的长度
	 *函数声名都是在string.h里面
	 */
	char str[10]="zhong";
	printf("%d\n",strlen(str)); //返回数组中的实际字符长度:5
	printf("%d",sizeof(str));  //返回数组在内存开辟的空间 单元 10
}

void clib_string_function_strlwr_strupr(){
		/**
		 * strlwr(字符串)  返回字符串的小写字母形式
		 * strupr(字符串) 返回字符串的大写字母形式
		 * 函数声名都是在string.h里面
		 */
	char l[]="ZHONG";
	printf("%s\n",strlwr(l)); //zhong

	char u[]="zhong";
	printf("%s\n",strupr(u));//ZHONG
}

//--------字符串练习-----------

//输入一串英文字符,求出有多少个单词,单词间出空格隔开
void count_word(){

	char string[100];
	gets(string);//从键盘中接收字符并赋值给数组

	int i,count=0;
	char c;
	for(i=0;(c=string[i])!='\0';i++){//一直循环到字符数组的结束标志'\0'才结束
		if(c==' '){
			count++;
		}
	}

	printf("在这一行里面,一共有%d个单词",count+1);
}

int main() {
//	printf_string();
//	scantf_string();
//	clib_string_function_puts();
//	clib_string_function_gets();
//	clib_string_function_strcat();
//	clib_string_function_strcpy_or_strncpy();
//	clib_string_function_strcmp();
//	clib_string_function_strlen();
//	clib_string_function_strlwr_strupr();
	count_word();
	return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-02 02:51:05

C语言学习笔记:19_数组-字符数组与字符串(常用字符串函数)的相关文章

C语言学习笔记(五) 数组

数组 数组的出现就是为了解决大量同类型数据的存储和使用的问题: 数组的分类:一维数组.二维数组. 一维数组:为多个变量连续分配存储控件:所有的变量的数据类型必须相同:所有变量所占的字节大小必须相等: 例如:int a[4]; 一维数组名不代表数组中的所有元素而是代表数组中第一个元素的地址: 数组的初始化: 完全初始化: int a[4] = {1,2,3,4}; 不完全初始化: int a[4] = {1};  未被初始化的元素的值默认为0; 数组清零 int a[4] = {0}; 不初始化:

Go语言学习笔记(三)数组 &amp; 切片 &amp; map

加 Golang学习 QQ群共同学习进步成家立业工作 ^-^ 群号:96933959 数组 Arrays 数组是同一种数据类型的固定长度的序列. 数组是值类型,因此改变副本的值,不会改变本身的值: 当作为方法的入参传入时将复制一份数组而不是引用同一指针. 通过从0开始的下标索引访问元素值. 数组定义 var a []int a = make([]int, 5) var a1 [5]int = [5]int{1, 2, 3, 4, 5} //len:5 content:[1 2 3 4 5] va

C语言学习笔记(六) 指针和数组

使用C语言就必然会使用到指针和数组.看下面的代码: int main(int argc, char** argv){     int a[4] = {1,3,5,7};     int *p = a;     int i;     for (i=0; i<4;i++){         printf("i=%d, p[i]=%d, *(p+i)=%d, a[i]=%d, *(a+i)=%d\n",                 i, p[i], *(p+i), a[i], *(

R语言学习笔记(十六):构建分割点函数

选取预测概率的分割点 cutoff<- function(n,p){ pp<-1 i<-0 while (pp>=0.02) { model.predfu<-rep("failure",n) model.predfu[model4.prob > 0.2 + i*0.001]<-"victory" pp<- abs(p-sum(model.predfu=="failure")/n) i<-i+1

JavaScript学习笔记【3】数组、函数、服务器端JavaScript概述

笔记来自<JavaScript权威指南(第六版)> 包含的内容: 数组 函数 服务器端JavaScript概述 数组 数组是动态的:根据需要它们会增长或缩减,并且在创建数组时无须声明一个固定的大小或在数组大小变化时无须重新分配空间. 数组可能是稀疏的:索引不一定要连续的,它们之间可以有空缺. 通常,数组的实现是经过优化的,用数字索引来访问数组元素一般来说比访问常规的对象属性要快很多. 数组继承自Array.prototype中的属性,它定义了一套丰富的数组操作方法. 如果省略数组直接量中的某个

C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com

原文:C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 本文由 arthinking 发表于315 天前 ⁄ itzhai.com原创文章 ⁄ C语言 ⁄ 评论数 3 ⁄ 被围观 1,775 views+ 指针数组: 在一个数组中,如果它的元素全部都是指针类

C语言--一维数组,字符数组

#import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { #pragma mark----------数组 //数组是容器,相同数据类型 //构造类型 // int a[3]={5,2,0}; //类型 // int[3]; //变量名 // a; //初值 // {5,2,0}; // int a[4] = {9,8,7,6}; // float b[6] = {2.5,3.14}; // char

【OpenGL 学习笔记04】顶点数组

通过之前的学习,我们知道,如果要绘制一个几何图形,那就要不断的调用绘制函数,比如绘制一个20条边的多边形,起码要调用22条函数(包含glBegin和glEnd). 所以OpenGL提供了一系列的顶点数组函数减少函数调用的次数来提高性能.而且使用顶点还可以避免顶点共享的冗余处理. 1.简单示例 先来回顾一下之前我们是怎么画直线的: void drawOneLine(GLfloat x1,GLfloat y1,GLfloat x2,GLfloat y2) { glBegin(GL_LINES); g

matlab学习笔记(一)单元数组

matlab学习笔记(一)单元数组 1.floor(x) :取最小的整数 floor(3.18)=3,floor(3.98)=3 ceil(x)  :取最大的整数 ceil(3.18)=4,ceil(3.18)=42.单元数组和结构体作用差不多, 相同点:都是存放不同类型的数据,能实现不同类型数据的存储机制. 不同点:结构体数组的 各个元素下有成员,并且每个成员有自己的名字,而单元数组没有成员和成员 名字的感念.3.单元数组,用[]表示元素间隔:用,表示元素之间的间隔:用:表示行间隔. 例如:c