首页 > 编程语言 >C++ 逆向之常用字符集互转

C++ 逆向之常用字符集互转

时间:2024-11-13 19:07:47浏览次数:1  
标签:std 编码 UTF 字符集 C++ len str 互转

在过往的编程过程中,常常会因为碰到字符集问题而头痛,而每次在进行字符集转换的时候,各种搜索网上文档,想找字符集转换的示例程序,但是都不尽人意,本篇文章的目的就是彻底解决之前编程过程中对字符集认识以及字符集转换之间似懂非懂、云里雾里的状态,并在文章结尾附上 ANSIUNICODEUTF-8 之间互转的代码。

一、ANSI 与 UNICODE

为了弄清楚编码之间的关系,我们首先来弄清楚编码的两个大类别:
ANSI:多字节字符集(MBCS),使用多个字节来表示一个字符,通常用于表示 ASCll 字符集之外的字符。在 MBCS 中, ASCll 字符(0-127)通常用一个字符表示,而其他字符则可能用两个字节或更多字节表示。MBCS 可以处理多种语言,但每种语言可能需要不同的编码页(code page)。常用的多字节字符集包括:GB2312GBKGB18030Big5 等。
UNICODE:使用固定长度的字节序列(通常是两个字节(UTF-16)或四个字节(UTF-32))来表示字符。Unicode 旨在提供一个统一的字符编码系统,可以表示世界上几乎所有的书写系统。常用的 Unicode 字符集包括:UTF-8UTF-16LEUTF-16BEUTF-32 等。

二、常见的 ANSI 编码

1 GB2312

1980 年,中国发布了第一个汉字编码标准,即 GB2312,全称《信息交换用汉字编码字符集·基本集》,通常简称 GB(“国标”汉语拼音首字母),共收录了 6763 个汉字和 682 个其他符号,包括拉丁字母、日文假名等,此标准于次年 5 月实施,满足了日常 99% 汉字的使用需求。

2 GBK

由于有些汉字是在 GB2312 标准发布后才简化的,还有一些人名、繁体字、日语和朝鲜语中的汉字也没有包括在内,所以在 GB2312 的基础上添加了这部分字符,就形成了 GBK,全称《汉字内码扩展规范》,包含 21003 个汉字和图形符号,包括繁体中文、日文假名、韩文等,完全兼容 GB2312,该字符集于 1995 年发布,支持简繁体中文,不过它只是“技术规范指导性文件”,并不属于国家标准。

3 GB18030

GB18030 全称《信息技术中文编码字符集》,它在 GBK 的基础上增加了中日韩语中的汉字和少数民族的文字及字符,完全兼容 GB2312 和 GBK,包括 70244 个汉字和图形符号,几乎覆盖了所有 Unicode 中收录的汉字,支持简繁体中文,并且与 Unicode 编码相兼容。

4 Big5

Big5 编码全称为大五码,是台湾地区广泛使用的中文编码标准,于 1984 年发布,最初包含 13053 个汉字,后来扩展到 21003 个,主要包含繁体中文字符,不包含简体中文字符,所以不兼容 GB2312 和 GBK。

三、常见的 UNICODE 编码

UTF(Unicode Transformation Format)是 Unicode 的编码方式,用于将 Unicode 字符编码成字节序列。

1 UTF-8

UTF-8 是一种变长编码方式,使用 1 到 4 个字节表示一个字符,UTF-8 编码与 ASCll 编码兼容(即 ASCll 字符在 UTF-8 中的编码与 ASCll 相同),所以对于英文字符,UTF-8 只需要一个字节,对于常用的汉字需要 3 个字节,对于较少使用的字符则需要 4 个字节,由于 UTF-8 的兼容性和对英文字符的高效编码,所以 UTF-8 在互联网上被广泛使用。

2 UTF-16LE

UTF-16LE(UTF-16 Little Endian)是一种固定长度的编码方式,使用 2 个字节表示基本多文种平面(BMP)中的字符,对于超出 BMP 的字符则需要 4 个字节,值得注意的是,UTF-16LE 为 UTF-16 的小端序编码,即低位字节在前,高位字节在后。现代大多数个人计算机和服务器使用的 x86 架构及其衍生体系多采用小端字节序,方便 CPU 进行计算,较为常用。

3 UTF-16BE

UTF-16BE(UTF-16 Big Endian)与 UTF-16LE 类似,区别在于 UTF-16BE 为 UTF-16 的大端序编码,即高位字节在前,低位字节在后,不怎么常用。

4 UTF-32

UTF-32 是一种固定长度的编码方式,使用 4 个字节表示任何 Unicode 字符,因此 UTF-32 在存储和处理上不如 UTF-8 和 UTF-16 高效,尤其对于 ASCll 和常用汉字。UTF-32 的编码也较为简单,每个 Unocde 码点直接对应一个 UTF-32 编码,不存在字节序问题,这种编码一般只在特定的场合和系统中使用。

四、常用编码之间的关系

上面讲了这么多编码,是不是感觉都要搞混乱了,其实我们只要区分好 GB2312GBKGB18030UTF-8 即可,其他编码比较容易分清楚。

它们四个的关系如下:

我们可以看到,ASCll 码其实是兼容性最高的,不管处于哪种编码下,英文字符都能够正常的显示,而对于中文字符,我们最常用的编码其实是 GBK,而 UTF-8 编码则最为通用,尤其在与网络相关的领域,比如浏览器中。

那到这里,可能有朋友可能会有疑问,我们平常用的编译器一般是用什么编码的呢?我们以 Visual Studio 2019 为例,一起来探究一下。

五、VS 编译器中的编码问题

VS2019 编译器中有两个地方经常涉及到编码问题,有的朋友可能没有弄得很清楚。第一个是在我们的项目属性中,里面有一个字符集设置。第二个是我们在写程序的时候,代码编辑区涉及到字符采用的编码形式。

1 项目属性中的字符集

右键项目属性 -> 配置属性 -> 高级 -> 字符集设置:

这里的字符集设置一般默认设置是使用 Unicode 字符集,这是什么意思呢?

我们在平常编写代码的过程中,会碰到需要以字符串作为参数传入的函数,比如 MessageBox,那么它就分为两个版本,分别为 MessageBoxAMessageBoxW,分别对应多字节字符集和 Unicode 字符集,当我们将此处的字符集设置为使用 Unicode 字符集时,MessageBox 这个宏会调用 MessageBoxW 这个版本:

2 代码编辑区中的字符集

除了上述可以设置字符集外,其实我们在编译器的代码编辑区也涉及到了字符集设置,不过一般编译器都是默认设置好了,不需要我们进行更改,而且随意进行更改很容易导致乱码问题,出于研究的目的,我们来看一下如何设置这个代码编辑区的字符集编码。

首先我们点击 VS 菜单栏中的 工具 -> 自定义 -> 命令 -> 菜单栏下拉框选择“文件” -> 点击添加命令 -> 类别 -> 点击文件 -> 添加高级保存选项 -> 点击确认:

接下来我们再点击 文件 -> 高级保存选项:

我们可以看到我们常用的字符集编码和对应的代码页都在里面,而默认的字符集编码是 GB2312,其实代码页 936 对应的是 GBK,因此其实我们的 VS2019 编译器使用的是 GBK 编码,这里的 GB2312-80 才是简版的 GB2312,下面是常用的字符集编码和对应的代码页,供大家参考:

字符集 代码页
GBK 936
Unicode(UTF-16LE) 1200
UTF-8 65001
GB18030 54936
GB2312 20936
Unicode(UTF-16BE) 1201
Big5 950

好了,现在我们搞清楚了编译器的默认编码,那这个有什么用呢?我们来看如下代码:

std::string test = "编码转换测试Test";

那我相信大家此刻就知道了 test 中存储的是 GBK 编码的字符串了,那 std::string 能不能存储其他字符集编码的字符串呢?答案是可以的,其实 std::string 可以存储任何编码类型的字符串,也就是它其实和字符串编码是完全独立的两个东西,只是平时我们编译器帮我们设置的默认字符集编码为 GBK,所以我们大家都会忽略 std::string 中存的到底是什么编码类型的字符串,在搞不清楚的情况下涉及到字符串编码转换的问题就会出现各种莫名其妙的乱码问题。

六、字符集编码测试

上面说了这么多理论知识,下面我们来测试一下,到底是不是这样的,我们以字符串“编码转换测试Test”为例进行测试,我们首先去下面的网址得到该字符串对应的不同字符集编码下的内存字节:
https://www.toolhelper.cn/EncodeDecode/EncodeDecode

然后开始我们的实验,代码如下:

// UTF-8:编码转换测试Test
	const char utf8_string[] = "\xE7\xBC\x96\xE7\xA0\x81\xE8\xBD\xAC\xE6\x8D\xA2\xE6\xB5\x8B\xE8\xAF\x95\x54\x65\x73\x74";
	// UTF-16LE(UTF-16 Little Endian):编码转换测试Test(尾部需要多添加一个 \x00 字节)
	const char utf16LE_string[] = "\x16\x7F\x01\x78\x6C\x8F\x62\x63\x4B\x6D\xD5\x8B\x54\x00\x65\x00\x73\x00\x74\x00\x00";
	// UTF-16BE(UTF-16 Big Endian):编码转换测试Test(尾部需要多添加一个 \x00 字节)
	const char utf16BE_string[] = "\x7F\x16\x78\x01\x8F\x6C\x63\x62\x6D\x4B\x8B\xD5\x00\x54\x00\x65\x00\x73\x00\x74\x00";
	// GBK(简繁体):编码转换测试Test
	const char gbk_string[] = "\xB1\xE0\xC2\xEB\xD7\xAA\xBB\xBB\xB2\xE2\xCA\xD4\x54\x65\x73\x74";
	// GB18030(中日韩):编码转换测试Test
	const char gb18030_string[] = "\xB1\xE0\xC2\xEB\xD7\xAA\xBB\xBB\xB2\xE2\xCA\xD4\x54\x65\x73\x74";
	// Big5(台湾繁体中文):編碼轉換測試Test
	const char big5_string[] = "\xBD\x73\xBD\x58\xC2\xE0\xB4\xAB\xB4\xFA\xB8\xD5\x54\x65\x73\x74";

	/*控制台输出测试*/
	// 控制台输出 UTF-8 编码的字符
	std::system("chcp 65001");    // 设置特定的代码页,否则控制台无法显示
	std::cout << utf8_string << std::endl;

	// 控制台输出 UTF-16LE(UNICODE,小端序,Little-Endian) 编码的字符
	setlocale(LC_ALL, "chs");    // 设置为输出简体中文的 Unicode
	std::wcout << (wchar_t*)utf16LE_string << std::endl;

	//windows 控制台无法直接输出 UTF-16BE(UNICODE,大端序,Big-Endian,) 编码的字符
	//大端先要转换成小端才能在控制台输出,因 x86 架构常用小端序,此处不再演示大端序字符打印

	// 控制台输出 GBK(简繁体) 编码的字符
	std::system("chcp 936");
	std::cout << gbk_string << std::endl;

	// 控制台输出 GB18030(中日韩) 编码的字符
	std::system("chcp 936");
	std::cout << gb18030_string << std::endl;

	// 控制台输出 Big5(台湾繁体中文) 编码的字符
	std::system("chcp 950");
	std::cout << big5_string << std::endl;

	/* 常见字符串数据类型的的字符默认存储形式 */
	// const char* 默认采用 GBK(简繁体) 编码
	char test1[] = "编码转换测试Test";
	std::cout << test1 << std::endl;

	// const wchar_t* 默认采用 UTF-16LE(UTF-16 Little Endian) 编码
	wchar_t test2[] = L"编码转换测试Test";
	setlocale(LC_ALL, "chs");    // 将程序的区域设置为简体中文,否则无法正确显示
	std::wcout << test2 << std::endl;
	
	// std::string 默认采用 GBK(简繁体) 编码
	std::string test3 = "编码转换测试Test";
	std::cout << test3 << std::endl;

	// std::wstring 默认采用 UTF-16LE(UTF-16 Little Endian) 编码
	std::wstring test4 = L"编码转换测试Test";
	setlocale(LC_ALL, "chs");
	std::wcout << test4 << std::endl;

我们可以看到,以上的字符串都能够以正常的格式输出,且 std::string 中默认为 GBK 编码。

有一个地方需要注意:UTF-16LE(UTF-16 Little Endian),由于我们定义的类型为 const char*,而 Unicode 一般以两个字节来表示一个中文字符,即使是最后的结尾 null 也是以两个字节 \00\00 来表示结尾的,而 const char* 只会在结尾添加一个结尾字符 \0,因此我们需要在定义的字符串后面多加上一个 \0,这样才不会出现乱码问题。

七、ANSI、UNICODE 和 UTF-8 编码互转

由于我们现在常用的编码为 GBKUnicode(UTF-16LE)UTF-8,因此我们可以近似的认为 ANSI 表示 GBKUnicode(UTF-16LE) 表示 UNICODE,下面提供这三种最常用字符集编码的两两互转函数供大家参考!

1 GBK(ANSI) 转 UTF-16LE(UNICODE)

// GBK(ANSI) 转 UTF-16LE(UNICODE)
bool gbk_to_utf16LE(const std::string& gbk_str, std::wstring& utf16le_str) {
	try {
		// 计算 GBK 转换后的宽字符数并为其分配内存空间
		int len = MultiByteToWideChar(CP_ACP, 0, gbk_str.c_str(), -1, NULL, 0);
		if (len == 0) {
			return false;
		}
		wchar_t* wstr = new wchar_t[len + 1];
		memset(wstr, 0, (len + 1) * sizeof(wchar_t));

		// 进行 utf16LE(UNICODE) 编码转换
		if (MultiByteToWideChar(CP_ACP, 0, gbk_str.c_str(), -1, wstr, len) == 0) {
			delete[] wstr;
			return false;
		}

		// 将 utf16LE(UNICODE) 编码的字符串赋值给输出参数
		utf16le_str = wstr;
		delete[] wstr;

		return true;
	}
	catch (const std::exception& e) {
		// 捕获并处理任何标准异常
		std::cerr << "gbk_to_utf16LE() Exception occurred: " << e.what() << std::endl;
		return false;
	}
	catch (...) {
		// 捕获任何非标准异常
		std::cerr << "gbk_to_utf16LE() Unknown exception occurred." << std::endl;
		return false;
	}
}

2 UTF-16LE(UNICODE) 转 GBK(ANSI)

// UTF-16LE(UNICODE) 转 GBK(ANSI)
bool utf16LE_to_gbk(const std::wstring& utf16LE_str, std::string& gbk_str) {
	try {
		// 计算 UNICODE 转换后的多字节字符数并为其分配内存空间
		int len = WideCharToMultiByte(CP_ACP, 0, utf16LE_str.c_str(), -1, NULL, 0, NULL, NULL);
		if (len == 0) {
			return false;
		}
		char* gbk_chars = new char[len + 1];
		memset(gbk_chars, 0, len + 1);

		// 进行 GBK 编码转换
		if (WideCharToMultiByte(CP_ACP, 0, utf16LE_str.c_str(), -1, gbk_chars, len, NULL, NULL) == 0) {
			delete[] gbk_chars;
			return false;
		}

		// 将 GBK 编码的字符串赋值给输出参数
		gbk_str = gbk_chars;
		delete[] gbk_chars;

		return true;
	}
	catch (const std::exception& e) {
		// 捕获并处理任何标准异常
		std::cerr << "utf16LE_to_gbk() Exception occurred: " << e.what() << std::endl;
		return false;
	}
	catch (...) {
		// 捕获任何非标准异常
		std::cerr << "utf16LE_to_gbk() Unknown exception occurred." << std::endl;
		return false;
	}
}

3 GBK(ANSI) 转 UTF-8

// GBK(ANSI) 转 UTF-8
bool gbk_to_utf8(const std::string& gbk_str, std::string& utf8_str) {
	try {
		// 计算 GBK 转换后的宽字符数并为其分配内存空间
		int len = MultiByteToWideChar(CP_ACP, 0, gbk_str.c_str(), -1, NULL, 0);
		if (len == 0) {
			return false;
		}
		wchar_t* wstr = new wchar_t[len + 1];
		memset(wstr, 0, (len + 1) * sizeof(wchar_t));

		// 将 GBK 转换为宽字符
		if (MultiByteToWideChar(CP_ACP, 0, gbk_str.c_str(), -1, wstr, len) == 0) {
			delete[] wstr;
			return false;
		}

		// 计算宽字符转换后的 UTF-8 编码字符数并为其分配内存空间
		len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
		if (len == 0) {
			delete[] wstr;
			return false;
		}
		char* utf8_chars = new char[len + 1];
		memset(utf8_chars, 0, len + 1);

		// 将宽字符转换为 UTF-8 编码
		if (WideCharToMultiByte(CP_UTF8, 0, wstr, -1, utf8_chars, len, NULL, NULL) == 0) {
			delete[] wstr;
			delete[] utf8_chars;
			return false;
		}

		// 将 UTF-8 编码的字符串赋值给输出参数
		utf8_str = utf8_chars;
		delete[] wstr;
		delete[] utf8_chars;

		return true;
	}
	catch (const std::exception& e) {
		// 捕获并处理任何标准异常
		std::cerr << "gbk_to_utf8() Exception occurred: " << e.what() << std::endl;
		return false;
	}
	catch (...) {
		// 捕获任何非标准异常
		std::cerr << "gbk_to_utf8() Unknown exception occurred." << std::endl;
		return false;
	}
}

4 UTF-8 转 GBK(ANSI)

// UTF-8 转 GBK(ANSI)
bool utf8_to_gbk(const std::string& utf8_str, std::string& gbk_str) {
	try {
		// 计算 UTF-8 转换后的宽字符数并为其分配内存空间
		int len = MultiByteToWideChar(CP_UTF8, 0, utf8_str.c_str(), -1, NULL, 0);
		if (len == 0) {
			return false;
		}
		wchar_t* wstr = new wchar_t[len + 1];
		memset(wstr, 0, (len + 1) * sizeof(wchar_t));

		// 将 UTF-8 转换为宽字符
		if (MultiByteToWideChar(CP_UTF8, 0, utf8_str.c_str(), -1, wstr, len) == 0) {
			delete[] wstr;
			return false;
		}

		// 计算宽字符转换后的 GBK 编码字符数并为其分配内存空间
		len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
		if (len == 0) {
			delete[] wstr;
			return false;
		}
		char* gbk_chars = new char[len + 1];
		memset(gbk_chars, 0, len + 1);

		// 将宽字符转换为 GBK 编码
		if (WideCharToMultiByte(CP_ACP, 0, wstr, -1, gbk_chars, len, NULL, NULL) == 0) {
			delete[] wstr;
			delete[] gbk_chars;
			return false;
		}

		// 将GBK编码的字符串赋值给输出参数
		gbk_str = gbk_chars;
		delete[] wstr;
		delete[] gbk_chars;

		return true;
	}
	catch (const std::exception& e) {
		// 捕获并处理任何标准异常
		std::cerr << "utf8_to_gbk() Exception occurred: " << e.what() << std::endl;
		return false;
	}
	catch (...) {
		// 捕获任何非标准异常
		std::cerr << "utf8_to_gbk() Unknown exception occurred." << std::endl;
		return false;
	}
}

5 UTF-16LE(UNICODE)转 UTF-8

// UTF-16LE(UNICODE)转 UTF-8
bool utf16LE_to_utf8(const std::wstring& utf16LE_str, std::string& utf8_str) {
	try {
		// 计算宽字符转换后的 UTF-8 编码字符数并为其分配内存空间
		int len = WideCharToMultiByte(CP_UTF8, 0, utf16LE_str.c_str(), -1, NULL, 0, NULL, NULL);
		if (len == 0) {
			return false;
		}
		char* utf8_chars = new char[len + 1];
		memset(utf8_chars, 0, len + 1);

		// 将宽字符转换为 UTF-8 编码
		if (WideCharToMultiByte(CP_UTF8, 0, utf16LE_str.c_str(), -1, utf8_chars, len, NULL, NULL) == 0) {
			delete[] utf8_chars;
			return false;
		}

		// 将 UTF-8 编码的字符串赋值给输出参数
		utf8_str = utf8_chars;
		delete[] utf8_chars;

		return true;
	}
	catch (const std::exception& e) {
		// 捕获并处理任何标准异常
		std::cerr << "unicode_to_utf8() Exception occurred: " << e.what() << std::endl;
		return false;
	}
	catch (...) {
		// 捕获任何非标准异常
		std::cerr << "unicode_to_utf8() Unknown exception occurred." << std::endl;
		return false;
	}
}

6 UTF-8 转 UTF-16LE(UNICODE)

// UTF-8 转 UTF-16LE(UNICODE)
bool utf8_to_utf16LE(const std::string& utf8_str, std::wstring& utf16LE_str) {
	try {
		// 计算 UTF-8 转换后的宽字符数并为其分配内存空间
		int len = MultiByteToWideChar(CP_UTF8, 0, utf8_str.c_str(), -1, NULL, 0);
		if (len == 0) {
			return false;
		}
		wchar_t* wstr = new wchar_t[len + 1];
		memset(wstr, 0, (len + 1) * sizeof(wchar_t));

		// 将 UTF-8 转换为宽字符
		if (MultiByteToWideChar(CP_UTF8, 0, utf8_str.c_str(), -1, wstr, len) == 0) {
			delete[] wstr;
			return false;
		}

		// 将宽字符赋值给输出参数
		utf16LE_str = wstr;
		delete[] wstr;

		return true;
	}
	catch (const std::exception& e) {
		// 捕获并处理任何标准异常
		std::cerr << "utf8_to_unicode() Exception occurred: " << e.what() << std::endl;
		return false;
	}
	catch (...) {
		// 捕获任何非标准异常
		std::cerr << "utf8_to_unicode() Unknown exception occurred." << std::endl;
		return false;
	}
}

7 调用示例

int main()
{
    ///* ANSI、UNICODE 和 UTF-8 编码互转 */
	std::string gbk_str;
	std::string utf8_str;
	std::wstring utf16LE_wstr;

	// GBK(ANSI) 转 UTF-16LE(UNICODE)
	gbk_to_utf16LE(gbk_string, utf16LE_wstr);
	setlocale(LC_ALL, "chs");
	std::wcout << utf16LE_wstr << std::endl;

	// UTF-16LE(UNICODE) 转 GBK(ANSI)
	utf16LE_to_gbk((wchar_t*)utf16LE_string, gbk_str);
	std::cout << gbk_str << std::endl;

	// GBK(ANSI) 转 UTF-8
	gbk_to_utf8(gbk_string, utf8_str);
	std::system("chcp 65001");
	std::cout << utf8_str << std::endl;

	// UTF-8 转 GBK(ANSI)
	utf8_to_gbk(utf8_string, gbk_str);
	std::cout << gbk_str << std::endl;

	// UTF-16LE(UNICODE)转 UTF-8
	utf16LE_to_utf8((wchar_t*)utf16LE_string, utf8_str);
	std::system("chcp 65001");
	std::cout << utf8_str << std::endl;
	
	// UTF-8 转 UTF-16LE(UNICODE)
	utf8_to_utf16LE(utf8_string, utf16LE_wstr);
	setlocale(LC_ALL, "chs");
	std::wcout << utf16LE_wstr << std::endl;

    return 0;
}

标签:std,编码,UTF,字符集,C++,len,str,互转
From: https://www.cnblogs.com/lostin9772/p/18543583

相关文章

  • 《深度解析 C++中的弱引用(weak reference):打破循环依赖的利器》
    在C++编程的世界里,内存管理一直是一个关键且复杂的话题。而弱引用(weakreference)的出现,为我们处理一些特殊的内存相关问题提供了一种巧妙的方法。今天,我们就来深入了解一下什么是弱引用。一、从引用的基本概念说起我们都知道,在C++中,引用是一种给变量起别名的方式。正常......
  • 告别头文件,编译效率提升 42%!C++ Modules 实战解析 | 干货推荐
    编者按:AlibabaCloudLinux(简称“Alinux”)是目前阿里云上占比第一的操作系统。2021年,龙蜥以Alinux产品为基础发布了AnolisOS8正式版。本文中,阿里云智能集团开发工程师李泽政以Alinux为操作环境,讲解模块相比传统头文件有哪些优势,并通过若干个例子,学习如何组织一个C++模......
  • 洛谷P11228的C++题解
    题目分析题目题目让我们算出机器人走步后经过了多少个不重复的点这道题不是搜索!直接按照题意模拟就行了。遇到墙就向右转,不是就直行。特别注意:向右转也是一步!一个格子最多算一遍!我们可以用一个标记数组 st,走过的点就打上标记。判断走道的点有没有打上标记,有就不......
  • 【最新原创毕设】面向课堂教学的智能课堂点名系统+09531(免费领源码)可做计算机毕业设计
    摘要本文旨在设计和实现一个基于智能课堂点名系统的智能助手。随着高校招生规模的不断扩大和信息化技术的发展,为教师提供一款便捷、全面的点名系统具有重要意义。本系统通过整合校园各项服务资源和功能,旨在帮助教师和学生更好地适应智能课堂,提供全方位的指导和支持。本文......
  • (2024最新毕设合集)基于SpringBoot的广州糖水甜品店推荐系统-28495|可做计算机毕业设计J
    摘要随着人们生活水平的提高和饮食习惯的多样化,甜品在日常生活中扮演着越来越重要的角色。特别是在中国南方地区,甜品店和糖水店已经成为人们经常光顾的地方,而广州作为美食之都,拥有众多具有独特风味的糖水甜品店。然而,由于市场竞争激烈,消费者往往面临选择困难,需要花费大量时间......
  • VS Code 关于C++代码运行时,工作目录不在于当前目录的问题(cwd)
    我在用C++练习流的使用时遇到了当前目录与工作目录不符的问题,导致使用相对路径时无法读取文件。这是我的工作目录其中1.txt内容为当我选择不使用插件执行代码时(如下)终端输出为:此时并没有将1.txt的内容输出出来,于是我运行,测试代码,输出当前的工作目录#include<iostream>......
  • C++函数传递引用或指针
    常见变量用法下面通过例子分别展示传递值、字符串、数组的用法示例代码#include<iostream>#include<string>//函数接受一个整数的引用和一个整数的指针voidmodifyValue(int&refValue,int*ptrValue){refValue=100;//通过引用修改值std::cout......
  • 用matlab算子提取相机亮度一致性曲线,转VC++实现
    用matlab的算子,提取相机亮度一致性曲线,用曲线调节相机亮度一致性。用C++开发,开发工具vs2019,使用迈德威视的相机。算法原理:间隔提取整副图像中的采集点,横向10点,竖向10点,均匀覆盖整图,采样不同曝光时间采集N帧图像,然后计算亮度的变化趋势,得到亮度曲线。读取原始图片,把......
  • 打卡信奥刷题(225)用C++工具信奥P1760[普及组/提高] 通天之汉诺塔
    通天之汉诺塔题目背景直达通天路·小A历险记第四篇题目描述在你的帮助下,小A成功收集到了宝贵的数据,他终于来到了传说中连接通天路的通天山。但是这距离通天路仍然有一段距离,但是小A突然发现他没有地图!!!但是幸运的是,他在山脚下发现了一个宝箱。根据经验判断(小A有经......
  • Foxit PDF Conversion SDK (C++, Linux ARM)-2.0.2
    FoxitPDFConversionSDKisaflexiblehigh-performancelibraryforconversionbetweenPDFfiles andMSOfficefileswhilemaintainingthelayoutandformatofyouroriginaldocuments.Itoffers advancedconversioncapabilitiesaswellasthesamequa......