字符串操作相关str函数+简易通讯录

复习:

字符串:

  由字符组成的串型结构,’\0’是它的结束标志

    存在形式:

      字符数组:栈内存,值可以修改,要为结束标志 ‘\0’ 预留位置

      字符串字面值:代码段,只读,值不可以被修改,修改会产生段错误,末尾会隐藏一个’ \0’

const char* str = “hehe”;

sizeof(“hehe”) = 5 末尾由 ‘\0’

sizeof(str) = 4 str是指针,字节恒为4|8

一般使用字符串字面值给字符数组初始化

char str[] = “hehe”

建议不设置数组长度

  
  字符串的输入:

    scanf (”%s“,str);  不能输入带空格的字符串

    gets(str);      可接空格,但不限制长度,有隐患

    fgets(str,size,stdin) 可设置最多接收size-1个字符(要为’\0’预留位置,如果输入的字符不足size-1,会把‘\n’ 一起接收,如果超出就丢弃超出部分)

  字符串的输出:

    printf(”%s“,str);

    puts(str); 会自动添加换行符

  
输出缓冲区:

  程序并不会立即把输出的数据显示到屏幕上,而是先存储在输出缓冲区,当满足一定条件时才显示

  1、遇到 \n

  2、程序结束

  3、遇到输入语句

  4、当缓冲区满4k时

  5、fflush(stdout)手动刷新

  缓冲区机制可以提高数据的读写速度,并且可以让低速的输入输出设备与高速的

CPU之间协调工作

输入缓冲区:

  程序并不会立即获取屏幕上输入的数据,而是按下回车键后,程序才从输入缓冲区读取数据

    1、当读需要读取的是整型或浮点型,而输入缓冲区中的数据是字符或符号时,

此时读取会失败,数据会残留在输入缓冲区中,就会影响接下来的所有数据的读取

    2、fgets()可以指定读取size-1个字符,如果有多余的会残留在输入缓冲区

中,影响下一次输入

    3、当先输入整型或浮点型数据,再紧接着输入字符、字符串时,前一次残留

的’\n’ 或空格,会影响字符、字符串的输入

  
  解决3:%c前面加空格

    scanf(” %c“,&ch)

  解决2:

    方法一:

      必须确认输入缓冲区中有垃圾数据时,才能去读取丢弃输入缓冲区的垃圾数据,否则程序会停下来等待缓冲区中有一个\n

scanf("%*[^\n]");//表示从缓冲区中接收任意字符并丢弃,只要不是\n就一直进行,遇到\n才停下
scanf("%*c");//丢弃任意字符,把\n丢掉

    方法二:

      借助缓冲区的位置指针移动到缓冲区的末尾,实现清理缓冲区的效果

      只能再Linux系统下使用

      stdin->_IO_read__ptr = stdin->_IO_read_end

  解决1:

    借助scanf返回值判断是否接收成功,如果接受过程有失败情况,可以先清理输入缓冲区,再重新循环接收数据,直到完全 接收成功为止

字符串相关的常用操作:

#include <string.h>
size_t strlen(const char *s);
//功能:计算字符串长度,不包括'\n'
//注意:sizeof和strlen的区别

char *strcpy(char *dest, const char *src);
//功能:把src拷贝到dest,相当于给dest赋值 (=)
//返回值:链式调用

char *strcat(char *dest, const char *src);
//功能:把字符串src追加到dest后面,相当于 += 运算
//返回值:返回dest,链式调用

int strcmp(const char *s1, const char *s2);
//功能:比较两个字符串的大小,按照字典序比较,谁在前面谁小,只要比较出结果,立即返回,后面的不再比较
//返回值:
	s1 > s2		正数
    s1 < s2		负数
    s1 == s2	0
#include <string.h>

char *strncpy(char *dest, const char *src, size_t n);
//功能:把src前n个字符拷贝给dest

char *strncat(char *dest, const char *src, size_t n);
//功能:把字符串前n个字符追加到dest后面

int strncmp(const char *s1, const char *s2, size_t n);
//功能:比较两个字符串前n个字符的大小

练习:重写实现strlen、strcpy、strcat、strcmp

重写strlen

#include <stdio.h>

size_t str_len(const char* str)
{
    const char* tmp =str;//都指向数组的首地址
	while(*tmp) tmp++;
    return tmp - str;
}
int main()
{
    char str[256] = "hehe";
    printf("str_len:%d\n",str_len);
}

重写strcpy

#include <stdio.h>

char* str_cpy(char* dest,const char* src)
{
    char* tmp = dest//备份dest首地址
	while(*tmp++ = *src++);
    return dest;
}
int main()
{
    char str[256] = "hehe";
    
    printf("str_cpy:%s\n",str_cpy(str,"abab"));
}

重写strcat

#include <stdio.h>

char* str_cat(char* dest,const char* src)
{
    char* tmp = dest;
    while(*tmp) tmp++;
    while(*tmp++ = *src++);
    return dest;
}
int main()
{
    char str[256] = "hehe";
    printf("str_cat:%s\n",str_cat(str,"abab"));
}

重写strcmp

#include <stdio.h>

int str_cmp(const char* s1,const char*s2)
{
    while(*s1 && *s1 == *s2) s1++,s2++;
    return *s1-*s2;
}
int main()
{
    char str[256] = "hehe";
    printf("str_cmp:%d\n",str_cat("ab","abc"));
}
#include <stdlib.h>

	int atoi(const char *nptr);
//功能:字符串转int类型
	long atol(const char *nptr);
//功能:字符串转long类型
	long long atoll(const char *nptr);
//功能:字符串转long long 类型

	double atof(const char *nptr);
//功能:字符串转double类型

   #include <string.h>

   char *strstr(const char *haystack, const char *needle);
//功能:查找haystack,是否存在needle
//返回值:needle首次在haystack中出现的首地址,如果找不到,返回NULL

if(NULL == strstr(haystack,needle))
    printf("没找到")
else
    printf("找到了")
    
    char *strchr(const char *s,int c);
//功能:查找s中是否有字符c
//返回值:c在s中首次出现的位置,不存在返回NULL
int sprintf(char *str, const char *format, ...);
//相当于字符串的拼接
//功能:把各种类型的数据输出到str中
//返回值:拼接后str的长度

int sscanf(const char *str, const char *format, ...);
//功能:从str中读取解析各种类型的数据
//返回值:成功读取到的变量的个数
#include <string.h>void *memcpy(void *dest, const void *src, size_t n);//功能:从src拷贝n个字节到dest中int memcmp(const void *s1, const void *s2, size_t n);

通讯录:

​ 姓名、性别、电话,最多存储50个联系人

​ 功能:

​ 1、添加联系人

​ 2、按姓名删除联系人

​ 3、按名字修改联系人信息

​ 4、查找联系人,姓名、电话,支持模糊查找

​ 5、显示所有联系人信息

#include <stdio.h>

#include <getch.h>

#include <stdlib.h>

#include <string.h>



static char name[50][20];

static char sex[50];

static char tel[50][13];

static int count = 0;	//有效联系人个数



//任意键继续

void anykey_continue(void)

{

	puts("任意键继续...");

	stdin ->_IO_read_ptr = stdin ->_IO_read_end;

	getch();

}



//打印提示信息

void show_msg(const char* msg,double sec)

{

	printf("%s",msg);

	fflush(stdout);		//刷新输出缓冲区

	usleep(sec*1000000);

}

void add(void)

{

	if(count >= 50)

	{

		printf("系统维护中,请稍后...\n");

		return;

	}

	int i =0;

	while(sex[i]) i++;

	printf("请输入姓名、性别、电话:\n");

	scanf("%s %c %s",name[i],&sex[i],tel[i]);

	count++;



	show_msg("添加联系人成功\n",1.5);

}



void del(void)

{	

	char key[20] = {};

	printf("请输入要删除的姓名:");

	scanf("%s",key);

	for(int i=0;i<50;i++)

	{

		if(sex[i])

		{

			if(0 == strcmp(name[i],key))	

			{

				printf("删除%s %s %s 联系人成功\n",name[i],sex[i] == 'w'?"女":"男",tel[i]);

				sex[i] = 0;

				count--;

				show_msg("",1.5);//不打印,但睡眠1.5秒;

				return 0;

			}

		}

	}

	printf("未找到联系人%s,请检查查询条件\n",key);

}



void modify(void)

{	

	char key[20] = {};

	printf("请输入需要修改信息的联系人:");

	scanf("%s",key);

	for(int i=0;i<50;i++)

	{

		if(sex[i])

		{

			if(0 == strcmp(name[i],key))

			{

				printf("请重新输入联系人姓名、性别、电话:");

				scanf("%s %c %s",name[i],&sex[i],tel[i]);

				show_msg("修改联系人成功!\n",1.5);

				return;

			}

		}

	}

	show_msg("未找到联系人,修改失败!\n",1.5);

}



void find(void)

{	

	char key[20] = {};

	printf("请输入需要查找的联系人信息(支持姓名、电话查找):\n");

	scanf("%s",key);

	for(int i =0;i<50;i++)

	{

		if(sex[i] && (strstr(name[i],key) || strstr(tel[i],key)))

		{

			printf("%s %s %s\n",name[i],sex[i] == 'w'?"女":"男",tel[i],tel[i]);

			show_msg("",2.5);

			return 0;

		}

	}

	anykey_continue();

}



void list(void)

{	

	for(int i =0;i<50;i++)

	{

		if(sex[i])

		{

			printf("%s %s %s\n",name[i],sex[i] == 'w'?"女":"男",tel[i]);	

		}

	}

	anykey_continue();

}



char menu(void)

{

	system("clear");

	puts("-----欢迎使用通讯录-----");

	puts("1、添加联系人");

	puts("2、删除联系人");

	puts("3、修改联系人");

	puts("4、查询联系人");

	puts("5、遍历联系人");

	puts("6、退出通讯录");

	puts("------------------------");

	puts("请输入指令:");

	char ch = getch();

	printf("%c\n",ch);	//为了显示按下的按键

	return ch;

}

int main(int argc,const char* argv[])

{

	for(;;)

	{

		switch(menu())

		{

			case '1':	add();		break;

			case '2':	del();		break;

			case '3':	modify();	break;

			case '4':	find();		break;

			case '5':	list();		break;

			case '6':	return 0;

		}

	}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值