【C/C++学院】0729-语音识别/Const关键字/字符串应用/内存分配以及处理海量数据

简介: <div style="top:0px"></div> <h1>语音识别</h1> <p>er.xml</p> <pre class="html" name="code"><?xml version="1.0" encoding="utf-8"?><GRAMMAR LANGID="804"> <DEFINE> <ID NAM


语音识别

er.xml

<?xml version="1.0" encoding="utf-8"?>
<GRAMMAR LANGID="804">
  <DEFINE>
    <ID NAME="CMD" VAL="10"/>
    </DEFINE>
  <RULE NAME="COMMAND" ID="CMD" TOPLEVEL="ACTIVE">
    <L>
      <P>资源管理器</P>
      <P>打开企鹅</P>
      <P>关闭企鹅</P>
      <P>关机</P>
      <P>重启</P>
      <P>记事本</P>
      <P>计算器</P>
      <P>画图板</P>
     <P>谭胜</P>
      </L>
    </RULE>
  </GRAMMAR>

yuyin.cpp

#include <windows.h>
#include <atlstr.h>
#include <sphelper.h>
#include <sapi.h>
#include<comutil.h>
#include<string.h>
#include<stdlib.h>

#pragma comment(lib,"sapi.lib")
#pragma comment(lib, "comsupp.lib") 

#define GID_CMD_GR 333333
#define WM_RECOEVENT WM_USER+1

 LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

 char 	 szAppName[] = "TsinghuaYincheng";
 BOOL b_initSR;
 BOOL b_Cmd_Grammar;
 CComPtr<ISpRecoContext>m_cpRecoCtxt;  //语音识别程序接口
 CComPtr<ISpRecoGrammar>m_cpCmdGramma; //识别语法
 CComPtr<ISpRecognizer>m_cpRecoEngine; //语音识别引擎


 int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow)
 {
	 HWND        hwnd;
	 MSG         msg;
	 WNDCLASS    wndclass;

	 wndclass.cbClsExtra          =0;
	 wndclass.cbWndExtra          =0;
	 wndclass.hbrBackground       =(HBRUSH)GetStockObject(WHITE_BRUSH);
	 wndclass.hCursor             =LoadCursor(NULL,IDC_ARROW);
	 wndclass.hIcon               =LoadIcon(NULL,IDI_APPLICATION);
	 wndclass.hInstance           =hInstance;
	 wndclass.lpfnWndProc         =WndProc;
	 wndclass.lpszClassName       =szAppName;
	 wndclass.lpszMenuName        =NULL;
	 wndclass.style               =CS_HREDRAW|CS_VREDRAW;

	 if(!RegisterClass(&wndclass))
	 {
		 MessageBox(NULL,TEXT("This program requires Windows NT!"),szAppName,MB_ICONERROR);
		 return 0;
	 }

	 hwnd=CreateWindow(szAppName,
		               TEXT("传智播客C/C++学院语音识别教程"),
					   WS_OVERLAPPEDWINDOW,
					   CW_USEDEFAULT,
					   CW_USEDEFAULT,
					   CW_USEDEFAULT,
					   CW_USEDEFAULT,
					   NULL,
					   NULL,
					   hInstance,
					   NULL);

	 ShowWindow(hwnd,iCmdShow);
	 UpdateWindow(hwnd);
	 
	 while(GetMessage(&msg,NULL,0,0))
	 {
		 TranslateMessage(&msg);
		 DispatchMessage(&msg);
	 }
	 return msg.wParam;
 }

 LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
 {
	 HDC           hdc;
	 PAINTSTRUCT   ps;

	 switch(message)
	 {
	 case WM_CREATE:
		 {
			 //初始化COM端口
			 ::CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);
			 //创建识别引擎COM实例为共享型
			 HRESULT hr=m_cpRecoEngine.CoCreateInstance(CLSID_SpSharedRecognizer);
			 //创建识别上下文接口
			 if(SUCCEEDED(hr))
			 {
				 hr=m_cpRecoEngine->CreateRecoContext(&m_cpRecoCtxt);
			 }
			 else MessageBox(hwnd,TEXT("error1"),TEXT("error"),S_OK);
			 //设置识别消息,使计算机时刻监听语音消息
			 if(SUCCEEDED(hr))
			 {
				 hr=m_cpRecoCtxt->SetNotifyWindowMessage(hwnd,WM_RECOEVENT,0,0);
			 }
			 else MessageBox(hwnd,TEXT("error2"),TEXT("error"),S_OK);
			 //设置我们感兴趣的事件
			 if(SUCCEEDED(hr))
			 {
				 ULONGLONG ullMyEvents=SPFEI(SPEI_SOUND_START)|SPFEI(SPEI_RECOGNITION)|SPFEI(SPEI_SOUND_END);
				 hr=m_cpRecoCtxt->SetInterest(ullMyEvents,ullMyEvents);
			 }
			 else MessageBox(hwnd,TEXT("error3"),TEXT("error"),S_OK);
			 //创建语法规则
			 b_Cmd_Grammar=TRUE;
			 if(FAILED(hr))
			 {
				 MessageBox(hwnd,TEXT("error4"),TEXT("error"),S_OK);
			 }
			 hr=m_cpRecoCtxt->CreateGrammar(GID_CMD_GR,&m_cpCmdGramma);
			 WCHAR wszXMLFile[20]=L"yuyinliebiao.xml";
			 MultiByteToWideChar(CP_ACP,0,(LPCSTR)"yuyinliebiao.xml",-1,wszXMLFile,256);
			 hr=m_cpCmdGramma->LoadCmdFromFile(wszXMLFile,SPLO_DYNAMIC);
			 if(FAILED(hr))
			 {
				 MessageBox(hwnd,TEXT("error5"),TEXT("error"),S_OK);
			 }
			 b_initSR=TRUE;
			 //在开始识别时,激活语法进行识别
		     hr=m_cpCmdGramma->SetRuleState(NULL,NULL,SPRS_ACTIVE);
	    	 return 0;
		 }
	 case WM_RECOEVENT:
		 {
			 RECT rect;
             GetClientRect(hwnd,&rect);
             hdc=GetDC(hwnd);
			 USES_CONVERSION;
			 CSpEvent event;
			 while(event.GetFrom(m_cpRecoCtxt)==S_OK)
			 {
			     switch(event.eEventId)
			     {
			     case SPEI_RECOGNITION:
    				 {
            			 static const WCHAR wszUnrecognized[]=L"<Unrecognized>";
		            	 CSpDynamicString dstrText;
			    		 //取得识别结果
				    	 if(FAILED(event.RecoResult()->GetText(SP_GETWHOLEPHRASE,SP_GETWHOLEPHRASE,TRUE,&dstrText,NULL)))
					     {
						     dstrText=wszUnrecognized;
    					 }
        	    		 BSTR SRout;
	        	    	 dstrText.CopyToBSTR(&SRout);
						 char* lpszText2 = _com_util::ConvertBSTRToString(SRout);

			    		 if(b_Cmd_Grammar)
				    	 {
							 if (strstr("资源管理器",lpszText2)!=NULL)
	    				     {    
								
								  system("C:\\");
								
				        		  DrawText(hdc,TEXT("资源管理器"),-1,&rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
					         }
							  if (strstr("打开企鹅",lpszText2)!=NULL)
	    				     {    
								
								  system("\"C:\\Program Files\\Tencent\\QQ\\QQProtect\\Bin\\QQProtect.exe\"");
				        		  DrawText(hdc,TEXT("打开企鹅"),-1,&rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
					         }
							  if (strstr("关闭企鹅", lpszText2) != NULL)
							  {
								  system("taskkill /f /im QQ.exe");
								  DrawText(hdc, TEXT("关闭企鹅"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
							  }
							  if (strstr("关机", lpszText2) != NULL)
							  {
								  system("shutdown -s -t 1200");
								  DrawText(hdc, TEXT("关机"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
							  }
							  if (strstr("重启", lpszText2) != NULL)
							  {
								  system("shutdown -r -t 1200");
								  DrawText(hdc, TEXT("重启"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
							  }
							  if (strstr("记事本", lpszText2) != NULL)
							  {
								  system("notepad");
								  DrawText(hdc, TEXT("记事本"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
							  }
							  if (strstr("计算器", lpszText2) != NULL)
							  {
								  system("calc");
								  DrawText(hdc, TEXT("计算器"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
							  }
							  if (strstr("画图板", lpszText2) != NULL)
							  {
								  system("mspaint");
								  DrawText(hdc, TEXT("画图板"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
							  }
							  if (strstr("谭胜", lpszText2) != NULL)
							  {

								  DrawText(hdc, TEXT("这是一个猥琐男"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
							  }


						
						
    					 }    
        			 }
	    		 }
			 }
			 return TRUE;
		 }
	 case WM_PAINT:
		 hdc=BeginPaint(hwnd,&ps);
		 EndPaint(hwnd,&ps);
		 return 0;
	 case WM_DESTROY:
		 PostQuitMessage(0);
		 return 0;
	 }
	 return DefWindowProc(hwnd,message,wParam,lParam);
 }

Const关键字


Const int *p; int const *p;


const *地址不可以修改


int *const p;


*const指向的数据不可修改

#include <stdio.h>

void main01()
{
	int num = 10;
	//const int data;
	//data = 20;
	const int data = 20;//const 修饰的变量,只能在初始化的时候进行赋值操作
	getchar();
}

//const在*左侧,地址本身不可以修改,可以改变指针指向。只能读不能写
void main02()
{
	int num = 10;
	const int data = 20;
	//const int *p;//等价于int const *p;
	int const *p;
	p = #
	printf("%d\n", *p);
	p = &data;
	printf("%d\n", *p);
	//*p = 30;//

	getchar();
}
//const在*右侧,指向的数据不可修改
void main()
{
	int num = 10;
	const int data = 20;
	int *const p = #//只能在初始化的时候,指定唯一的指向

	//int *const p;
	//p = #
	printf("%d\n", *p);
	//p = &data;
	*p = 30;
	printf("%d\n", *p);
	getchar();
}

void main04()
{
	int num = 10;
	const int data = 20;
	const int *const p = #
	printf("%d\n", *p);
	//*p = 30;
	//p = &data;

	getchar();
}

字符串应用

#define  _CRT_SECURE_NO_WARNINGS //关闭安全检查
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <Windows.h>

void main1()
{
	//char str[100] = "for /l %i in (1,1,5) do calc";
	//char *p = "for /l %i in (1,1,5) do calc";
	//str[0] = ' '; str是数组,存储的是字符串每一个字符
	//*p = ' ';p是一个指针,存储字符串的地址

	char str[100] = { 0 };
	//printf("for /l %%i in (1,1,%d) do %s",5,"calc");
	int num;
	char op[30] = { 0 };
	scanf("%d%s", &num, op);
	sprintf(str, "for /l %%i in (1,1,%d) do %s", num, op);
	system(str);

	system("pause");
}

void main2()
{
	char str[100] = { 0 };
	char op[30] = { 0 };
	scanf("%s", op);
	sprintf(str, "taskkill /f /im %s", op);
	system(str);

	system("pause");
}

void main3()
{
	system("tasklist");
	for (int i = 0x0; i <= 0xf; i++)
	{
		char str[30] = { 0 };//存储指令
		sprintf(str, "color %x%x", i,0xf-i);//打印指令
		system(str);//变色
		Sleep(500);
	}
}

void  main4()
{
	char str[100] = "我有1000元";
	int num;
	sscanf(str, "我有%d元", &num);
	printf("%d", num);

	system("pause");
}

void main5()
{
	//printf("%.6s\n", "1234.abcd");
	char str[100] = "notepad8888";
	char newstr[100] = "";
	sprintf(newstr, "%.s", str);
	system(newstr);

	system("pause");
}

void  main6()
{
	char str1[100] = "note";
	char str2[100] = "pad";
	//system(str1 + str2);
	char str3[100] = { 0 };
	sprintf(str3, "%s%s", str1, str2);//字符串相加
	system(str3);
}

void main7()
{
	//printf("%.6s", "1234.abcd");
	char str[100] = "notepad8888";
	char newstr[100] = "";
	sprintf(newstr, "%-10.7s", str);//10宽度,+宽度范围内右边对齐,-左边对齐,.7从左往右挖去7个字符
	printf("[%s]", newstr);
	system(newstr);

	system("pause");
}

int mystrlen(char* str)
{
	int i = 0;
	for (char*p = str; *p != '\0'; p++)
	{
		i++;
	}
	return i;//实现字符串统计
}

int mystrlenA(char* str)
{
	char *p = str;
	int i = 0;
AAA: if (*p!='\0')
{
		 i++;
		 p++;
		 goto AAA;
}
	 return i;
}

int mystrlenB(char *str)
{
	if (*str=='\0')
	{
		return 0;
	}
	else
	{
		return 1 + mystrlenB(++str);
	}
}

void  main8()
{
	char str[100] = "china is good";
	printf("%d", sizeof(str));//求数组缓冲区长度
	printf("\n%d", mystrlen(str));//从开头第一个字符到\0字符
	printf("\n%d", mystrlenA(str));//从开头第一个字符到\0字符
	printf("\n%d", mystrlenB(str));//从开头第一个字符到\0字符
	getchar();
}

void main9()
{
	char str1[100] = "my name is yincheng";
	char str2[30] = "chen";
	char *p = strstr(str1, str2);
	if (p == NULL)
	{
		printf("没有找到");
	}
	else
	{
		printf("找到%p,%c, %s", p, *p, p);
	}
	getchar();
}


内存分配以及处理海量数据

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

// m, n生成一个数组,m行 n列
void main()
{
	int *p =(int*) malloc(sizeof(int)* 40);//一维数组
	for (int *px = p,i=0; px < p + 40; px++,i++)//
	{
		*px = i;//赋值
		printf("%d,%p\n", *px, px);//指针循环
	}
	//int b[5][8];
	printf("\n\n\n");
	int(*pp)[8] = (int(*)[8]) p;//指针类型决定了访问的方式
	for (int i = 0; i < 5; i++)
	{
		for (int j = 0; j < 8; j++)
		{
			//printf("%5d", pp[i][j]);//打印数据
			printf("%5d", *(*(pp + i) + j));// pp[i][j]
		}
		printf("\n");
	}
	//a [4][2][5]
	printf("\n\n\n");
	int(*ppp)[2][5] = (int(*)[2][5])p;
	for (int i = 0; i < 4; i++)
	{
		for (int j = 0; j < 2; j++)
		{
			for (int k = 0; k < 5; k++)
			{
				//printf("%5d", ppp[i][j][k]);//打印元素
				printf("%5d", *(*(*(ppp + i) + j) + k));
			}
			printf("\n");
		}
		printf("\n\n\n");
	}

	system("pause");
}


#define  _CRT_SECURE_NO_WARNINGS //关闭安全检查
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

char **pp=NULL;//存储指针数组的地址

//13180807 *4  /1024/1024  50M

void initdatatomem(char *path)
{
    pp  = (char **)malloc(sizeof(char *)* 13180807);//分配指针数组
	FILE *pf = fopen(path, "r");
	if (pf == NULL)
	{
		printf("fail");
	}
	else
	{		
		for (int i = 0; i < 13180807; i++)
		{
			char str[275] = {0};//读取字符串的缓冲区
			fgets(str, 275, pf);//从文件中逐行读取字符串
			int  strlength = strlen(str) + 1;//获取要分配的字符串长度
			char *px =(char *) malloc(sizeof(char)*strlength);//分配内存
			strcpy(px, str);//拷贝字符串
			px[strlength - 1] = '\0';//设定最后一个字符为'\0'
			pp[i] = px;//存储字符串的首地址到指针数组
		}
	}
	printf("载入内存OK\n");
}

void  findstr(char *searchstr)
{
	for (int i = 0; i < 13180807; i++)
	{
		//pp[i];//是一个指针
		char *ptemp = strstr(pp[i], searchstr);//遍历所有的指针数组的地址,字符串查找
		if (ptemp != NULL)
		{
			printf("\n%s", pp[i]);//打印字符串
		}
	}
}

int getfilesize(char *path)
{
	FILE *pf;//文件指针
	pf = fopen(path, "r");//读取的模式打开
	if (pf == NULL)
	{
		return -1;//代表获取失败
	}
	else
	{
		fseek(pf, 0, SEEK_END);//到文件末尾
		int num = ftell(pf);//文件开头到当前位置有多少个字节
		fclose(pf);//关闭文件
		return num;
	}
}

int getn(char *path)
{
	FILE *pf;//文件指针
	pf = fopen(path, "r");//读取的模式打开
	if (pf == NULL)
	{
		return -1;//代表获取失败
	}
	else
	{
		int i = 0;
		while (!feof(pf))//是否到文件末尾
		{
			char str[275];
			fgets(str, 275, pf);//读取一行
			i++;//统计行数
		}
		fclose(pf);//关闭文件
		return i;
	}
}

void main()
{
	/*char *path = "C:\\Users\\yincheng01\\Desktop\\old\\dangdangwang.txt";
	int num = getfilesize(path);
	printf("%d字节,%fK,%fM", num, num / 1024.0, num / 1024.0 / 1024.0);
	printf("\n有%d行", getn(path));*/
	char *path = "C:\\Users\\yincheng01\\Desktop\\old\\dangdangwang.txt";
	initdatatomem(path);
	while (1)
	{
		char searchstr[100] = { 0 };
		scanf("%s", searchstr);
		findstr(searchstr);
	}
	system("pause");
}


相关实践学习
达摩院智能语音交互 - 声纹识别技术
声纹识别是基于每个发音人的发音器官构造不同,识别当前发音人的身份。按照任务具体分为两种: 声纹辨认:从说话人集合中判别出测试语音所属的说话人,为多选一的问题 声纹确认:判断测试语音是否由目标说话人所说,是二选一的问题(是或者不是) 按照应用具体分为两种: 文本相关:要求使用者重复指定的话语,通常包含与训练信息相同的文本(精度较高,适合当前应用模式) 文本无关:对使用者发音内容和语言没有要求,受信道环境影响比较大,精度不高 本课程主要介绍声纹识别的原型技术、系统架构及应用案例等。 讲师介绍: 郑斯奇,达摩院算法专家,毕业于美国哈佛大学,研究方向包括声纹识别、性别、年龄、语种识别等。致力于推动端侧声纹与个性化技术的研究和大规模应用。
目录
相关文章
|
4天前
|
存储 安全 编译器
【C++入门 四】学习C++内联函数 | auto关键字 | 基于范围的for循环(C++11) | 指针空值nullptr(C++11)
【C++入门 四】学习C++内联函数 | auto关键字 | 基于范围的for循环(C++11) | 指针空值nullptr(C++11)
|
5天前
|
算法 C++
2730. 找到最长的半重复子字符串(c++,滑动窗口)
2730. 找到最长的半重复子字符串(c++,滑动窗口)
|
5天前
|
C++
567. 字符串的排列(c++)滑动窗口
567. 字符串的排列(c++)滑动窗口
|
11天前
|
语音技术
语音识别-------求1-100的和讲解,while循环猜数字的实例,用while设置while循环猜数字的案例,while循环的嵌套应用,while嵌套while如何去做,表白送花写法,九九乘法表
语音识别-------求1-100的和讲解,while循环猜数字的实例,用while设置while循环猜数字的案例,while循环的嵌套应用,while嵌套while如何去做,表白送花写法,九九乘法表
|
12天前
|
存储 C语言 C++
【C/C++】动态内存管理( C++:new,delete)
C++的`new`和`delete`用于动态内存管理,分配和释放内存。`new`分配内存并调用构造函数,`delete`释放内存并调用析构函数。`new[]`和`delete[]`分别用于数组分配和释放。不正确匹配可能导致内存泄漏。内置类型分配时不初始化,自定义类型则调用构造/析构。`operator new`和`operator delete`是系统底层的内存管理函数,封装了`malloc`和`free`。定位`new`允许在已分配内存上构造对象,常用于内存池。智能指针等现代C++特性能进一步帮助管理内存。
|
12天前
|
编译器 C++
【C++】string类的使用④(字符串操作String operations )
这篇博客探讨了C++ STL中`std::string`的几个关键操作,如`c_str()`和`data()`,它们分别返回指向字符串的const char*指针,前者保证以&#39;\0&#39;结尾,后者不保证。`get_allocator()`返回内存分配器,通常不直接使用。`copy()`函数用于将字符串部分复制到字符数组,不添加&#39;\0&#39;。`find()`和`rfind()`用于向前和向后搜索子串或字符。`npos`是string类中的一个常量,表示找不到匹配项时的返回值。博客通过实例展示了这些函数的用法。
|
12天前
|
存储 编译器 程序员
【C/C++】动态内存管理(C:malloc,realloc,calloc,free)
探索C++与C语言的动态内存管理:从malloc到new/delete,了解内存分布及栈、堆的区别。文章涵盖malloc、realloc、calloc与free在C中的使用,强调内存泄漏的风险。C++引入new和delete,支持对象构造与析构,还包括operator new和placement-new。深入分析内存管理机制,揭示C与C++在内存处理上的异同。别忘了,正确释放内存至关重要!
|
5天前
|
安全 算法 编译器
C++一分钟之-内存模型与数据竞争
【7月更文挑战第10天】了解C++11内存模型对多线程编程至关重要。它定义了线程间同步规则,包括顺序一致性、原子操作和内存屏障。数据竞争可能导致不确定行为,如脏读和丢失更新。可通过互斥量、原子操作和无锁编程避免竞争。示例展示了`std::mutex`和`std::atomic`的使用。掌握内存模型规则,有效防止数据竞争,确保多线程安全和性能。
11 0
|
11天前
|
语音技术 数据安全/隐私保护
语音识别,猜猜心里数字讲解,猜数字的组合,判断语句的嵌套,嵌套语句使用很简单,我们写一个外层嵌套的条件,利用缩进,满足条件,才会执行条件2,判断语句综合案例,如何产生变量的随机数字,while循环应用
语音识别,猜猜心里数字讲解,猜数字的组合,判断语句的嵌套,嵌套语句使用很简单,我们写一个外层嵌套的条件,利用缩进,满足条件,才会执行条件2,判断语句综合案例,如何产生变量的随机数字,while循环应用
|
13天前
|
存储 Java 程序员
Python和C++在内存管理方面有什么不同?
【7月更文挑战第2天】Python和C++在内存管理方面有什么不同?
13 0