项目开发常用字符串应用模型

上一章 《 c语言指针详解 》



一、 字符串查找字符串个数

strstr中的while和do-while模型

C标准库 – <string.h>
char * strstr(const char * 要被检索的字符串, const char * 要搜索的小字符串)
该函数返回在 要被检索的字符串 中第一次出现 小字符串 的位置,如果未找到则返回 null。

1)while模型

字符串出现次数

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

int main() {
	//字符串出现次数
	char* s = "123456you I wander in your yard, looking forward to meeting you";
	char c[] = "you";
	int num = 0;
	while ((s = strstr(s, c)) != NULL)
	{
		//有匹配字符串,重新设置起点位置
		s = s + strlen(c);
		num++;
	}
	printf("个数: %d\n", num);//3
	return 0;
}

C标准库 – <string.h>
strlen()函数:该函数从第一个字符开始计算字符串中字符数,直到遇到空字符即’\0’为止,然后返回计算字符数的长度,包括’\0’。

2)do-while模型

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

int main() {
	//字符串出现次数
	char* s = "123456you I wander in your yard, looking forward to meeting you";
	int num = 0;
	char c[] = "you";
	s = strstr(s, c);
	do
	{
		if (s) { //s!=NULL
			num++;
			s += strlen(c);
			s = strstr(s, c);
		}
	} while (s);


	printf("个数: %d\n", num);//3
	return 0;
}

二、 字符串查找字符个数

获取非空格字符串个数(两头堵模型)

只不计算前后的空格,中间的空格会计入。

这个模型就是找两个变量,一个从字符串的开始遍历,另一个从字符串的末尾开始遍历,最后得到中间想要的信息。假设有一个字符串前后都有好多好多空格" Iwanderinyouryard " , 最后得到前后不为空的子串长度 17。

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

int fun(char* p, int* n)
{
	if (p == NULL || n == NULL)
	{
		return -1;
	}

	int begin = 0;
	int end = strlen(p) - 1;

	//从左边开始
	while (p[begin]==' ' && p[begin] != 0)//若果当前字符为空,且没有结束
	{
		begin++;//位置向右移动一位
	}

	//从右往左移动
	while (p[end] == ' ' && end > 0)
	{
		end--;//往左移动
	}

	if (end == 0) {
		return -2;
	}
	//非空元素个数
	*n = end - begin + 1;

	return 0;
}


int main()
{
	char* p = "  Iwanderinyouryard   ";
	int ret = 0;
	int n = 0;

	ret = fun(p, &n);
	if (ret != 0)
	{
		return ret;
	}
	printf("个数n:%d\n", n);//17

	return 0;
}

所有空格字符都不记

1)数组版

#include <stdio.h>

//获取非空格字符串个数
int GetStrNonBlankCount(char* str)
{
	int i = 0;
	int count = 0;
	while (str[i])
	{
		if (str[i] != ' ')
		{
			count++;
		}
		i++;
	}
	return count;
}

int main()
{
	char str[] = "   I wander in your yard   ";
	int count = GetStrNonBlankCount(str);
	printf("非空格字符串个数: %d\n", count);//17
	return 0;
}

2)指针版

#include <stdio.h>

//获取非空格字符串个数
int GetStrNonBlankCount(char* str)
{
	int count = 0;
	while (*str)
	{
		//if ( *str != ' ')
		if (*str != 32) //32是空格
		{
			count++;
		}
		str++;
	}
	return count;
}

int main()
{
	char str[] = "   I wander in your yard   ";
	int count = GetStrNonBlankCount(str);
	printf("非空格字符串个数: %d\n", count);//17
	return 0;
}

字符串去所有空格

#include<stdio.h>

//字符串去空格
void RemoveSpace(char* s)
{
	//用来遍历字符串
	char* ftemp = s;
	//记录非空格字符串的
	char* rtemp = s;
	while (*ftemp)
	{
		if (*ftemp != ' ') {
			*rtemp = *ftemp;
			rtemp++;
		}
		ftemp++;
	}
	*rtemp = 0;
}

int main() {
	char s[] = "   h  e l lo x   y ";
	RemoveSpace(s);
	printf("s:%s\n", s);//helloxy
	return 0;
}

三、统计不同字符出现的个数

#include <stdio.h>
#include <string.h>
int main(void)
{
	char str[] = "iwanderinyouryardlookingforwardtomeetingyou";//97 97+25
	int counts[26] = {0};
	//直接插入排序
	for (int i = 0; i < strlen(str); i++)
	{
		counts[(str[i] - 'a')]++;
	}
	
	for (int i = 0 ;i < 26; i++)
	{
		if(counts[i])
			printf("字母:%c\t出现次数:%d\n", 'a'+i, counts[i]);
	}

	return 0;
}

在这里插入图片描述

注意:char str[] = " I wander in your yard "; 栈区字符串
char* s = “123456you I wander in your yard, looking forward to meeting you”; 数据区常量区字符串

四、字符串反转模型(字符串逆置)

1)

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

void InverseString(char* s) 
{
	int i = 0;
	int j = strlen(s) - 1;
	while (i<j)
	{
		char temp = s[i];
		s[i] = s[j];
		s[j] = temp;
		i++;
		j--;
	}
}

int main(void) {
	char s[] = "looking forward to meeting you";
	InverseString(s);
	printf("%s\n",s);//uoy gniteem ot drawrof gnikool
	return 0;
}

2)

void InverseString(char* s) 
{
	char* ftemp = s;
	char* btemp = s + strlen(s) - 1;
	while (ftemp < btemp) 
	{
		char temp = *ftemp;
		*ftemp = *btemp;
		*btemp = temp;
		ftemp++;
		btemp--;
	}
}

判断是不是回文字符串

末尾和前面都是相同的(是不是对称),例如 abcba 、abccba

#include <stdio.h>

int Symm(char* s) //symmetry
{
	char* ftemp = s;
	char* btemp = s + strlen(s) - 1;
	while (ftemp < btemp)
	{
		if (*ftemp != *btemp)//不相同
			return 1;
		ftemp++;
		btemp--;
	}
	return 0;//相同
}

int main() 
{
	char s[] = "abcba";
	int value = Symm(s);
	if (!value){//value=0
		printf("对称\n");
	}
	else {
		printf("不对称\n");
	}
	return 0;
}

五、字符串处理函数

字符串拷贝

strcpy

#define _CRT_SECURE_NO_WARNINGS 放在文件开始,防止此文件因为一些老的.c文件使用了strcpy,scanf等不安全的函数导致报警告和错误,使其无法编译通过,不安全的
#include <string.h>
char * strcpy(char * dest,const char *src);
把src所指向的字符串复制到dest所指向的空间中,'\0’也会拷贝过去


参数:

  • dest: 目的字符串首地址
  • src: 源字符首地址

返回值:

  • 成功:返回dest字符串的首地址
  • 失败:NULL


注意:如果参数 dest 所指的内存空间不够大,可能会造成缓冲溢出的错误情况,所以使用 strcpy 也是不安全的行为。

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

int main() {
	char ch[] = "hello xy";
	char s[100];
	
	strcpy(s,ch);

	printf("%s\n",s);//hello xy

	return 0;
}

strncpy

char *strncpy(char *dest, const char *src, size_t n);
功能:把src指向字符串的前n个字符复制到 dest 所指向的空间中,是否拷贝结束符看指定的长度是否包含'\0'


参数:

  • dest:目的字符串首地址
  • src:源字符首地址
  • n:指定需要拷贝字符串个数

返回值:

  • 成功:返回dest字符串的首地址
  • 失败:NULL

没有拷贝到’\0’
在这里插入图片描述
我们把字符串初始化一下,这样就不会烫烫烫烫烫烫…了

#define _CRT_SECURE_NO_WARNINGS 
#include <stdio.h>
#include <string.h>
int main() {
	char ch[] = "hello xy";
	char s[100]={0};
	//字符串有限拷贝
	strncpy(s,ch,3);
	printf("%s\n", s);//hel
	return 0;
}

ch总共就9个,拷贝20个会怎么样?

答:可以,拷贝到 ‘\0’ 就结束了
在这里插入图片描述

字符串追加

strcat

#include<string.h>
char * strcat(char *dest, const char *src);
功能:将src字符串连接到dest的尾部, '\0' 也会追加过去

参数:

  • dest:目的字符串首地址
  • src:源字符首地址

返回值:

  • 成功:返回dest字符串的首地址
  • 失败:NULL
#define _CRT_SECURE_NO_WARNINGS 
#include <stdio.h>
#include<string.h>

int main(void) 
{
	char dest[100] = "hello";
	char src[] = "world";

	strcat(dest, src);
	printf("===%s====\n",dest);//helloworld

	return 0;
}

如果dest没有足够空间,程序就会挂掉了,没有足够空间就属于数组下标越界了,这里面应该有足够空间去做一个字符串追加。

在这里插入图片描述

strncat

char *strncat(char *dest, const char *src, size_t n);
功能:把src字符串前n个字符连接到 dest 的尾部,'\0' 也会追加过去


参数:

  • dest:目的字符串首地址
  • src:源字符首地址
  • n:指定需要追加字符串个数,大于长度就把整段字符串追加过去了

返回值:

  • 成功:返回dest字符串的首地址
  • 失败:NULL
#define _CRT_SECURE_NO_WARNINGS 
#include <stdio.h>
#include <string.h>

int main(void) 
{
	char dest[100] = "hello";
	char src[] = "world";

	strncat(dest, src,3);
	printf("===%s====\n",dest);//hellowor

	return 0;
}

字符串比较

strcmp

#include <string.h>.
int strcmp(const char *s1,const char *s2);
功能:比较s1和s2的大小、比较的是字符ASCII码大小

参数:

  • s1:字符串1首地址
  • s2:字符串2首地址

返回值:

  • 相等:0
  • 大于:>0 在不同操作系统strcmp结果会不同,有的返回ASClI差值,有的是返回 1
  • 小于:<0 有的返回ASClI差值,有的是返回 -1
#define _CRT_SECURE_NO_WARNINGS 
#include <stdio.h>
#include <string.h>

int main(void)
{
	char s1[] = "hello xy";
	char s2[] = "hello xy";

	int val = strcmp(s1,s2);
	printf("%d\n",val);//0
	return 0;
}

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
遇到 ‘\0’
在这里插入图片描述

strncmp

#include <string.h>.
int strncmp(const char *s1,const char *s2, size_t n);
功能:比较s1和s2前n个字符的大小、比较的是字符ASCII码大小

参数:

  • s1:字符串1首地址
  • s2:字符串2首地址
  • n:指定比较字符串的数量

返回值:

  • 相等:0
  • 大于:>0 在不同操作系统strcmp结果会不同,有的返回ASClI差值,有的是返回 1
  • 小于:<0 有的返回ASClI差值,有的是返回 -1
#define _CRT_SECURE_NO_WARNINGS 
#include <stdio.h>
#include <string.h>

int main(void)
{
	char s1[] = "hello xy";
	char s2[] = "hello xy";

	int val = strncmp(s1,s2,5);
	printf("%d\n",val);//0
	return 0;
}

遇到 ‘\0’
在这里插入图片描述

字符串格式化 sprintf

#include <stdio.h>
int sprintf(char *str, const char *format,…);
功能:根据参数format字符串来转换并格式化数据。然后将结果输出到str指定的空间中,直到出现字符串结束符’\0’为止。

参数:

  • str:字符串首地址
  • format:字符串格式,用法和printf()一样

返回值:

  • 成功:实际格式化的字符个数
  • 失败:-1
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main()
{
	char s[100];
	//sprintf(s,"hello xy");
	//sprintf(s,"%d + %d = %d",1,2,3);
	sprintf(s,"===%5d + %05d = %-05d===",1,2,3);

	printf("%s\n",s);
	return 0;
}

字符串读取数据 sscanf

#include <stdio.h>
int sscanf(const char *str, const char *format,…);
功能:从str指定的字符串读取数据,并根据参数format字符串来转换并格式化数据。

参数:

  • str:指定的字符串首地址
  • format:字符串格式,用法和scanf()一样

返回值:

  • 成功:参数数目,成功转换的值的个数
  • 失败:-1
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main()
{
	char s[]="a1+12-3";
	int a, b, c;
	sscanf(s,"%x+%o-%d",&a,&b,&c);

	printf("%d,%d,%d\n",a,b,c);//161,10,3
	return 0;
}

但是在看这个,当遇到空格或者换行时,跟scanf一样当结束标志处理了
在这里插入图片描述
解决办法:我们可以用正则表达式"%[^\n]"
在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main()
{
	char s[] = "hello xy";
	char ch[100];
	char ch2[100];

	//sscanf(s, "%s", &ch);//失败:hello
	//sscanf(s, "%9s", &ch);//失败:hello
	//sscanf(s, "%[^\0]", &ch);//失败:烫烫烫烫烫烫烫烫烫烫烫烫烫···
	//sscanf(s, "%[^\n]", &ch);//hello xy
	/*  只截取一部分  */
	//sscanf(s, "%3s", &ch);//成功:hel
	sscanf(s, "%s%s", &ch, &ch2);//成功:ch="hello"  ch2="xy"
	//sscanf(s, "%3s%s", &ch, &ch2);//ch="hel" ch2="lo"

	printf("===%s===\n", ch);
	printf("===%s===\n", ch2);
	return 0;
}

字符串查找

字符串里查找字符 strchr

#include <string.h>
char *strchr(const char * s, int c);
功能:在字符换s中查找字母c出现的位置

参数:

  • s:字符串首地址
  • c:匹配字母(字符)

返回值:

  • 成功:返回第一次出现的c地址
  • 失败: NULL
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>

int main()
{
	char s[] = "hello xy";
	char c = 'x';
	//找得到
	char* p = strchr(s, c);
	printf("%s\n", p);//xy

	//没有找到
	c = 'a';
	p = strchr(s, c);
	printf("%s\n", p);//(null)
	return 0;
}

字符串里查找字符串 strstr

#include <string.h>
char *strstr(const char * haystack, const char* needle);
功能:在字符换haystack中查找字符串needle出现的位置

参数:

  • haystack:源字符串首地址
  • needle:匹配字符串首地址

返回值:

  • 成功:返回第一次出现的needle地址
  • 失败: NULL

字符串分割(截取) strtok

#include <string.h>
char *strtok(const char * str, const char* delim);
功能:来将字符串分割成一个个片段。当strtok()在参数s的字符串中发现参数delim中包含的分割字符时,则会将该字符改为’\0’字符,当连续出现多个时只替换第一个为’\0’。

参数:

  • str:指向欲分割的字符串
  • delim:为分割字符串中包含的所有字符

返回值:

  • 成功:分割后字符串首地址
  • 失败: NULL

strtok会破坏源字符串,用\0替换分割的标志位,“https://blog.csdn.net/weixin_59633478/” 变成 “https://blog\0csdn.net/weixin_59633478/”

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

int main()
{
	char s[] = "https://blog.csdn.net/weixin_59633478/";

	printf("%p\n", s);//00000088CC70F938
	//strtok会破坏源字符串,用\0替换分割的标志位
	char* p = strtok(s,".");//"https://blog\0csdn.net/weixin_59633478/"

	printf("%p\n",s);//00000088CC70F938
	printf("%p\n",p);//00000088CC70F938

	printf("%s\n",p);//https://blog
	printf("%s\n",s);//https://blog
	printf("%c\n",s[13]);//c
	return 0;
}

如果还想让字符串继续截取,第二次截取的时候不是s而是NULL,因为s现在是\0了,这里面就没有值了而是传递NULL,因为字符串没有截取完,他在缓存区还会保留一份字符串,如果你再想截取就写个NULL。p = strtok(NULL, ".");

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

int main()
{
	char s[] = "https://blog.csdn.net/weixin_59633478/";
	//https://blog\0csdn\0net/weixin_59633478/

	//第一次截取
	char* p = strtok(s,".");
	printf("%s\n",p);/*  https://blog    */

	//第二次截取
	p = strtok(NULL, ".");
	printf("%s\n", p);/*  csdn  */

	//第三次截取
	p = strtok(NULL, ".");
	printf("%s\n", p);/*  net/weixin_59633478/  */

	return 0;
}

截取邮箱

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

int main()
{
	char s[] = "123456789@163.com";
	//以@为标志进行截取
	char s2[100] = { 0 };

	strcpy(s2, s);

	//第一次截取
	char* p = strtok(s2,"@");
	printf("%s\n",p);/*  123456789   */

	//第二次截取
	p = strtok(NULL, ".");
	printf("%s\n", p);/*  163   */

	return 0;
}

循环截取

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

int main()
{
	char s[] = "I\nwander\nin\nyour yard, looking\nforward\nto\nmeeting\nyou.";
	
	//第一次截取
	char* p = strtok(s,"\n");

	//判断p是不是NULL
	while (p)
	{
		printf("%s\n", p);
		p = strtok(NULL, "\n");
	}

	return 0;
}

在这里插入图片描述

字符串类型转换

a to i

#include <stdlib.h>
int atoi(const char *nptr);
功能:atoi()会扫描nptr字符串,跳过前面的空格字符,直到遇到数字或正负号才开始做转换,而遇到非数字或字符串
结束符(‘\0’)才结束转换,并将结果返回返回值。

参数:

  • nptr:待转换的字符串

**返回值:**成功转换后整数,如果失败就是0了

类似的函数有:
atof():把一个小数形式的字符串转化为一个浮点数double类型。
atol():将一个字符串转化为 long 类型。
#include <stdlib.h>
#include <stdio.h>

int main() {
	char s[] = "   -123-666abc";

	//从+-号或者数字开始识别,遇到非数字就停止
	int i = atoi(s);

	printf("%d\n", i);//-123

	return 0;
}

注意:只能识别十进制的整数
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 Python 中,可以使用 SQLAlchemy 来实现 ORM(Object-Relational Mapping)模型。SQLAlchemy 是一个功能强大的 Python 库,可以方便地连接各种数据库,并提供了一组高级 API 来操作数据库。 使用 SQLAlchemy 实现 ORM 模型的一般步骤如下: 1. 安装 SQLAlchemy 库: ``` pip install sqlalchemy ``` 2. 创建一个 SQLAlchemy 的引擎,用于连接数据库: ```python from sqlalchemy import create_engine engine = create_engine("数据库连接字符串") ``` 3. 创建一个基类,用于定义 ORM 模型的共同属性和方法: ```python from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() ``` 4. 定义 ORM 模型: ```python from sqlalchemy import Column, Integer, String class User(Base): __tablename__ = "users" id = Column(Integer, primary_key=True) name = Column(String) age = Column(Integer) ``` 5. 创建 ORM 模型对应的数据表: ```python Base.metadata.create_all(engine) ``` 6. 创建一个会话,用于操作数据库: ```python from sqlalchemy.orm import sessionmaker Session = sessionmaker(bind=engine) session = Session() ``` 7. 使用会话来操作数据库,如插入数据、查询数据等: ```python # 插入数据 user = User(name="Alice", age=20) session.add(user) session.commit() # 查询数据 users = session.query(User).all() ``` 有关 SQLAlchemy 的更多信息,可以参考官方文档 ### 回答2: Python实现数据库ORM模型的方式有很多,最常用的两种方式是使用SQLAlchemy和Django框架。 1. 使用SQLAlchemy:SQLAlchemy是一个Python开发的数据库工具包,它提供了灵活的ORM(对象关系映射)模型,可以方便地操作数据库。实现步骤如下: a. 首先,需要安装SQLAlchemy库,可以使用pip命令进行安装:pip install sqlalchemy b. 接下来,建立一个数据库连接:通过创建一个Engine对象,指定数据库的类型和连接信息。 c. 定义数据表结构:通过继承SQLAlchemy的Base类,创建一个ORM模型类,并在类中定义数据表的结构和字段。 d. 创建数据库会话:通过创建一个Session对象,使用session进行数据库操作,如插入、查询、更新等操作。 2. 使用Django框架:Django是一个强大的Web开发框架,它集成了ORM模型,并提供了方便的数据库操作方法。实现步骤如下: a. 首先,需要安装Django框架,可以使用pip命令进行安装:pip install Django b. 创建一个Django项目应用:通过运行命令django-admin startproject myproject,创建一个Django项目;然后通过运行命令python manage.py startapp myapp,创建一个应用。 c. 配置数据库连接:在项目的settings.py文件中,配置数据库的连接信息,指定数据库的类型和连接信息。 d. 定义数据表结构:在应用的models.py文件中,定义一个ORM模型类,并在类中定义数据表的结构和字段。 e. 进行数据库迁移:通过运行命令python manage.py makemigrations和python manage.py migrate,将ORM模型映射为数据库表,并创建对应的数据表结构。 以上是使用SQLAlchemy和Django框架实现Python数据库ORM模型的方法,两种方法都很常用,可以根据实际需要选择合适的方式。 ### 回答3: Python中有许多流行的数据库ORM模型,其中最常用的是SQLAlchemy。下面是Python如何使用SQLAlchemy实现数据库ORM模型的简要步骤: 首先,需要在Python中安装SQLAlchemy模块,可以使用pip命令在终端或命令提示符中运行以下命令安装: ```shell pip install SQLAlchemy ``` 接下来,导入所需的模块: ```python from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String from sqlalchemy.orm import sessionmaker ``` 创建数据库引擎并连接到数据库: ```python engine = create_engine('数据库连接字符串') ``` 使用`declarative_base`函数创建一个基类用于定义数据库表格模型: ```python Base = declarative_base() ``` 定义数据库表格模型: ```python class User(Base): __tablename__ = 'users' id = Column(Integer, primary_key=True) username = Column(String) password = Column(String) ``` 创建表格: ```python Base.metadata.create_all(engine) ``` 创建一个数据库会话: ```python Session = sessionmaker(bind=engine) session = Session() ``` 使用会话进行数据库操作: ```python # 创建一个用户 new_user = User(username='foo', password='bar') session.add(new_user) session.commit() # 查询用户 user = session.query(User).filter_by(username='foo').first() print(user.username) print(user.password) # 更新用户 user.password = 'new_password' session.commit() # 删除用户 session.delete(user) session.commit() ``` 通过以上步骤,Python就可以使用SQLAlchemy实现数据库ORM模型,实现对数据库的增删改查操作。注意,这只是一个简化的示例,并且在实际应用中可能会有更多的操作和复杂的关系映射。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值