C语言通过MSXML6.0读写XML文件(同时支持char[]和wchar_t[]字符数组)

开发环境:Visual Studio 2010
运行环境:Windows XP SP3

第一节 读取XML文件(使用wchar_t[]字符数组)

/* 这个程序只能在C编译器下编译成功, 请确保源文件的扩展名为c */
#define COBJMACROS
#include <stdio.h>
#include <MsXml6.h>#pragma comment(lib, "msxml6.lib")/*
参考资料:(1) VARIANT结构体: https://msdn.microsoft.com/en-us/library/windows/desktop/dd373687(v=vs.85).aspxVARIANT用于表示一个弱类型的变量(2) BSTR字符串: https://msdn.microsoft.com/en-us/library/windows/desktop/ms221069(v=vs.85).aspxBSTR字符串是用于COM组件对象模型的字符串格式, 字符串以表示字符串长度的4字节整数开始, 然后跟上UTF-16编码的wchar_t字符串(包括\0结束标志)。BSTR类型的变量是一个指针, 指向字符串的第一个字符处例如, 一段起始地址为1000的内存空间, 则1000~1003这四个字节存放字符串的长度, 1004开始才是字符串的真正内容, BSTR变量应指向1004而不是1000wchar_t *用于保存UTF-16编码格式的字符串, 用wprintf的%ls输出char *可以用来保存任意编码格式的字符串, 但只有ANSI格式才能使用printf的%s正确显示出来在简体中文版操作系统下, ANSI就是GB2312编码MultiByteToWideChar函数可以将char *字符串转换为wchar_t *字符串WideCharToMultiByte函数可以将wchar_t *字符串转换为char *t字符串SysAllocString函数可以将wchar_t *字符串转换为BSTR字符串(3) IXMLDOMDocument接口: https://msdn.microsoft.com/en-us/library/windows/desktop/dd892951(v=vs.85).aspx(4) 组件对象模型COM: https://msdn.microsoft.com/en-us/library/windows/desktop/ff485848(v=vs.85).aspxhttps://msdn.microsoft.com/en-us/library/windows/desktop/ms680573(v=vs.85).aspx(5) Windows窗口程序: https://msdn.microsoft.com/en-us/library/windows/desktop/ff381409(v=vs.85).aspx
*/// C语言自带的wprintf函数无法打印中文
// 所以这里重新实现一个能打印中文的my_wprintf函数
int my_wprintf(const wchar_t *format, ...)
{int n;va_list list;wchar_t str[1024];DWORD ret;HANDLE console;va_start(list, format);n = _vsnwprintf_s(str, _countof(str), _countof(str) - 1, format, list);va_end(list);console = GetStdHandle(STD_OUTPUT_HANDLE);WriteConsoleW(console, str, (DWORD)wcslen(str), &ret, NULL);return n;
}// 显示元素节点的属性值 (元素节点是一种节点)
void display_attribute(IXMLDOMElement *elem, const wchar_t *name, int intval)
{int num;BSTR bstr; // 表示一个字符串VARIANT variant; // 表示一个弱类型的变量bstr = SysAllocString(name); // 必须用SysAllocString函数把wchar_t *字符串转换成BSTR字符串IXMLDOMElement_getAttribute(elem, bstr, &variant);SysFreeString(bstr); // 使用完字符串后必须释放my_wprintf(L"[Attribute] name=%ls, value=%ls", name, variant.bstrVal); // BSTR和wchar_t *字符串都用%ls输出if (intval){num = _wtoi(variant.bstrVal); // 转换为整形printf(", 2*value=%d", 2 * num);}printf("\n");SysFreeString(variant.bstrVal); // 保存在Variant中的BSTR也必须释放掉
}// 显示节点名称
void display_nodename(IXMLDOMNode *node)
{BSTR bstr;IXMLDOMNode_get_nodeName(node, &bstr);my_wprintf(L"[Node] name=%ls\n", bstr); // 使用%ls打印BSTR字符串内容SysFreeString(bstr); // 使用完字符串后必须释放
}// 显示节点中的文本内容 (方法一)
void display_content(IXMLDOMNode *node)
{BSTR text;IXMLDOMNode_get_text(node, &text);my_wprintf(L"[Text] %ls\n", text);SysFreeString(text);
}// 显示节点中的文本内容 (方法二)
// 文本内容是文本节点, 是node节点下的子节点
/*
void display_content(IXMLDOMNode *node)
{IXMLDOMNode *child;VARIANT value;IXMLDOMNode_get_firstChild(node, &child); // 获取文本节点IXMLDOMNode_get_nodeValue(child, &value); // 得到文本节点的内容my_wprintf(L"[Text] %ls\n", value.bstrVal);SysFreeString(value.bstrVal);IXMLDOMNode_Release(child);
}
*/// 获取节点中的XML文本内容
void display_inner_xml(IXMLDOMNode *node)
{BSTR bstr;IXMLDOMNode_get_xml(node, &bstr);my_wprintf(L"[InnerXML] %ls\n", bstr);SysFreeString(bstr);
}void read_xml(IXMLDOMDocument *xmldoc)
{long i, len;IXMLDOMElement *root;IXMLDOMElement *elem;IXMLDOMNode *root_node;IXMLDOMNode *item;IXMLDOMNodeList *list;// 根节点IXMLDOMDocument_get_documentElement(xmldoc, &root);IXMLDOMNode_QueryInterface(root, &IID_IXMLDOMNode, &root_node); // 把element node变为nodedisplay_nodename(root_node);display_attribute(root, L"id", 1);display_inner_xml(root_node);printf("\n");// 根节点下的子节点IXMLDOMElement_get_childNodes(root, &list);IXMLDOMNodeList_get_length(list, &len);for (i = 0; i < len; i++){IXMLDOMNodeList_get_item(list, i, &item);display_nodename(item);display_content(item);// 只有元素节点才有属性节点, 所以获取属性前要进行类型转换, 把node变为element nodeIXMLDOMNode_QueryInterface(item, &IID_IXMLDOMElement, &elem);display_attribute(elem, L"name", 0);IXMLDOMElement_Release(elem);IXMLDOMNode_Release(item);}IXMLDOMNodeList_Release(list);IXMLDOMElement_Release(root_node);IXMLDOMNodeList_Release(root);
}// 打开XML文件
void open_xml(const wchar_t *name)
{HRESULT hr;IXMLDOMDocument *xmldoc;VARIANT filename;VARIANT_BOOL flag;hr = CoCreateInstance(&CLSID_DOMDocument60, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, &xmldoc);if (SUCCEEDED(hr)){filename.bstrVal = SysAllocString(name); // 将wchar_t *转换为BSTRfilename.vt = VT_BSTR;IXMLDOMDocument_load(xmldoc, filename, &flag);// 注: IXMLDOMDocument_load是读XML文件//     IXMLDOMDocument_loadXML是读XML字符串SysFreeString(filename.bstrVal);if (flag == VARIANT_TRUE){printf("读取XML文件成功\n");read_xml(xmldoc);}elseprintf("读取XML文件失败\n");IXMLDOMDocument_Release(xmldoc);}
}int main()
{CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); // 初始化COM组件对象模型open_xml(L"data.xml");CoUninitialize();return 0;
}

 

第二节 读取XML文件(使用char[]字符数组)

/* 这个程序只能在C编译器下编译成功, 请确保源文件的扩展名为c */
#define COBJMACROS
#include <stdio.h>
#include <MsXml6.h>#pragma comment(lib, "msxml6.lib")// char *转BSTR
// 用完后调用SysFreeString释放
BSTR convert_string_to_bstr(const char *s)
{int n;wchar_t *ws;BSTR bstr = NULL;n = MultiByteToWideChar(CP_ACP, 0, s, -1, NULL, 0);ws = malloc(n * sizeof(wchar_t));if (ws != NULL){MultiByteToWideChar(CP_ACP, 0, s, -1, ws, n);bstr = SysAllocString(ws);free(ws);}return bstr;
}// BSTR转char *
// 用完后调用free释放
char *convert_bstr_to_string(BSTR bstr)
{char *s;int n;n = WideCharToMultiByte(CP_ACP, 0, bstr, -1, NULL, 0, NULL, NULL);s = malloc(n);if (s != NULL)WideCharToMultiByte(CP_ACP, 0, bstr, -1, s, n, NULL, NULL);return s;
}// 显示元素节点的属性值 (元素节点是一种节点)
void display_attribute(IXMLDOMElement *elem, const char *name, int intval)
{char *value_str;int num;BSTR bstr; // 表示一个字符串VARIANT variant; // 表示一个弱类型的变量bstr = convert_string_to_bstr(name);IXMLDOMElement_getAttribute(elem, bstr, &variant);SysFreeString(bstr); // 使用完字符串后必须释放value_str = convert_bstr_to_string(variant.bstrVal);printf("[Attribute] name=%s, value=%s", name, value_str);if (intval){num = atoi(value_str); // 转换为整形printf(", 2*value=%d", 2 * num);}printf("\n");free(value_str);SysFreeString(variant.bstrVal); // 保存在Variant中的BSTR也必须释放掉
}// 显示节点名称
void display_nodename(IXMLDOMNode *node)
{char *s;BSTR bstr;IXMLDOMNode_get_nodeName(node, &bstr);s = convert_bstr_to_string(bstr);printf("[Node] name=%s\n", s);free(s);SysFreeString(bstr); // 使用完字符串后必须释放
}// 显示节点中的文本内容 (方法一)
void display_content(IXMLDOMNode *node)
{char *text_str;BSTR text;IXMLDOMNode_get_text(node, &text);text_str = convert_bstr_to_string(text);printf("[Text] %s\n", text_str);free(text_str);SysFreeString(text);
}// 显示节点中的文本内容 (方法二)
// 文本内容是文本节点, 是node节点下的子节点
/*
void display_content(IXMLDOMNode *node)
{char *value_str;IXMLDOMNode *child;VARIANT value;IXMLDOMNode_get_firstChild(node, &child); // 获取文本节点IXMLDOMNode_get_nodeValue(child, &value); // 得到文本节点的内容value_str = convert_bstr_to_string(value.bstrVal);printf("[Text] %s\n", value_str);free(value_str);SysFreeString(value.bstrVal);IXMLDOMNode_Release(child);
}
*/// 获取节点中的XML文本内容
void display_inner_xml(IXMLDOMNode *node)
{char *s;BSTR bstr;IXMLDOMNode_get_xml(node, &bstr);s = convert_bstr_to_string(bstr);printf("[InnerXML] %s\n", s);free(s);SysFreeString(bstr);
}void read_xml(IXMLDOMDocument *xmldoc)
{long i, len;IXMLDOMElement *root;IXMLDOMElement *elem;IXMLDOMNode *root_node;IXMLDOMNode *item;IXMLDOMNodeList *list;// 根节点IXMLDOMDocument_get_documentElement(xmldoc, &root);IXMLDOMNode_QueryInterface(root, &IID_IXMLDOMNode, &root_node); // 把element node变为nodedisplay_nodename(root_node);display_attribute(root, "id", 1);display_inner_xml(root_node);printf("\n");// 根节点下的子节点IXMLDOMElement_get_childNodes(root, &list);IXMLDOMNodeList_get_length(list, &len);for (i = 0; i < len; i++){IXMLDOMNodeList_get_item(list, i, &item);display_nodename(item);display_content(item);// 只有元素节点才有属性节点, 所以获取属性前要进行类型转换, 把node变为element nodeIXMLDOMNode_QueryInterface(item, &IID_IXMLDOMElement, &elem);display_attribute(elem, "name", 0);IXMLDOMElement_Release(elem);IXMLDOMNode_Release(item);}IXMLDOMNodeList_Release(list);IXMLDOMElement_Release(root_node);IXMLDOMNodeList_Release(root);
}// 打开XML文件
void open_xml(const char *name)
{HRESULT hr;IXMLDOMDocument *xmldoc;VARIANT filename;VARIANT_BOOL flag;hr = CoCreateInstance(&CLSID_DOMDocument60, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, &xmldoc);if (SUCCEEDED(hr)){filename.bstrVal = convert_string_to_bstr(name); // 将char *转换为BSTRfilename.vt = VT_BSTR;IXMLDOMDocument_load(xmldoc, filename, &flag);// 注: IXMLDOMDocument_load是读XML文件//     IXMLDOMDocument_loadXML是读XML字符串SysFreeString(filename.bstrVal);if (flag == VARIANT_TRUE){printf("读取XML文件成功\n");read_xml(xmldoc);}elseprintf("读取XML文件失败\n");IXMLDOMDocument_Release(xmldoc);}
}int main()
{CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); // 初始化COM组件对象模型open_xml("data.xml");CoUninitialize();return 0;
}

第三节 读取XML字符串(使用char[]字符数组)

// 读取XML字符串
void load_xml_str()
{char *str = "<?xml version=\"1.0\" encoding=\"utf-8\"?><data id=\"20240117\"><post name=\"2023年人口统计数据发布了,大家怎么看?\">建档788W是主体,压哨建档出生的一部分,双胞胎三胞胎占一小部分,不建档生孩子的占一小部分,但是还是难凑出902,还是得预支一下。</post><post name=\"有什么是去了成都才知道的?\">不要跟团,也不要自驾游,成都每天都人满为患,人多车堵,还不好停车,景点大部分集中在1、2、3号线,坐地铁出行就能玩转成都。2、去鹤鸣茶社品一品茶,享受宁静时光感受成都的慢生活与惬意。3、成都火锅很辣,不是很能吃辣的朋友一定不要轻易尝试,不然会被辣的怀疑人生。</post><post name=\"能否找到一个f(x),使得当x取到全体正整数的时候,f(x)可以取到全体有理数?\">题主好像没有要求是单射啊……如果只要求满射的话,其实有个简单粗暴的做法,就是把正整数劈开……</post><post name=\"C++ 有什么好用的线程池?\">题主说的那两个thread pool其实都不错,但是2024年肯定是更推荐这一个,这个就是为进入标准的senders所实现的,学了也不会白学,当然它的使用非常简单。</post><post name=\"有什么适合大学生喝的性价比高的茶?\">虽然现代社会,买东西都在追求性价比,但茶叶这东西,我觉得还真不好说!</post></data>";BSTR bstr;HRESULT hr;IXMLDOMDocument *xmldoc;VARIANT_BOOL succeeded;hr = CoCreateInstance(&CLSID_DOMDocument60, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, &xmldoc);if (SUCCEEDED(hr)){bstr = convert_string_to_bstr(str);hr = IXMLDOMDocument_loadXML(xmldoc, bstr, &succeeded);// 注: IXMLDOMDocument_load是读XML文件//     IXMLDOMDocument_loadXML是读XML字符串SysFreeString(bstr);if (SUCCEEDED(hr)){if (hr == S_OK){printf("读取XML字符串成功\n");read_xml(xmldoc);}else if (hr == S_FALSE)printf("读取XML字符串失败\n");}// 另一种判断是否成功的方式if (succeeded == VARIANT_TRUE)printf("succeeded=true\n");else if (succeeded == VARIANT_FALSE)printf("succeeded=false\n");IXMLDOMDocument_Release(xmldoc);}
}int main()
{CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); // 初始化COM组件对象模型load_xml_str();CoUninitialize();return 0;
}

第四节 创建XML文件(使用char[]字符数组)

/* 这个程序只能在C编译器下编译成功, 请确保源文件的扩展名为c */
#define COBJMACROS
#include <stdio.h>
#include <time.h>
#include <MsXml6.h>#pragma comment(lib, "msxml6.lib")// char *转BSTR
// 用完后调用SysFreeString释放
BSTR convert_string_to_bstr(const char *s)
{int n;wchar_t *ws;BSTR bstr = NULL;n = MultiByteToWideChar(CP_ACP, 0, s, -1, NULL, 0);ws = malloc(n * sizeof(wchar_t));if (ws != NULL){MultiByteToWideChar(CP_ACP, 0, s, -1, ws, n);bstr = SysAllocString(ws);free(ws);}return bstr;
}// BSTR转char *
// 用完后调用free释放
char *convert_bstr_to_string(BSTR bstr)
{char *s;int n;n = WideCharToMultiByte(CP_ACP, 0, bstr, -1, NULL, 0, NULL, NULL);s = malloc(n);if (s != NULL)WideCharToMultiByte(CP_ACP, 0, bstr, -1, s, n, NULL, NULL);return s;
}void create_header(IXMLDOMDocument *xmldoc)
{BSTR target, data;IXMLDOMNode *header_node;IXMLDOMProcessingInstruction *header;// 创建XML文档头节点target = convert_string_to_bstr("xml");data = convert_string_to_bstr("version=\"1.0\" encoding=\"utf-8\"");IXMLDOMDocument_createProcessingInstruction(xmldoc, target, data, &header);SysFreeString(target);SysFreeString(data);// header转换成node, 然后添加进文档// 注意旧的header对象和新产生的node对象都要释放IXMLDOMProcessingInstruction_QueryInterface(header, &IID_IXMLDOMNode, &header_node);IXMLDOMProcessingInstruction_Release(header);IXMLDOMDocument_appendChild(xmldoc, header_node, NULL); // 最后一个参数是输出参数, 没有用IXMLDOMNode_Release(header_node);
}IXMLDOMElement *create_root(IXMLDOMDocument *xmldoc)
{char timestr[30];struct tm tm;time_t t;BSTR name;IXMLDOMElement *root;IXMLDOMNode *root_node;VARIANT value;// 创建根节点name = convert_string_to_bstr("data");IXMLDOMDocument_createElement(xmldoc, name, &root);SysFreeString(name);// 将创建的根节点添加到文档中IXMLDOMElement_QueryInterface(root, &IID_IXMLDOMNode, &root_node);IXMLDOMDocument_appendChild(xmldoc, root_node, NULL);IXMLDOMNode_Release(root_node);// 获取当前时间time(&t);localtime_s(&tm, &t);strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", &tm);// 在根节点上添加一个属性name = convert_string_to_bstr("timestr");value.bstrVal = convert_string_to_bstr(timestr);value.vt = VT_BSTR;IXMLDOMElement_setAttribute(root, name, value);SysFreeString(name);SysFreeString(value.bstrVal);return root;
}void add_post(IXMLDOMDocument *xmldoc, IXMLDOMElement *root, const char *name, const char *text)
{BSTR attrname_bstr;BSTR nodename_bstr;BSTR text_bstr;IXMLDOMElement *elem;IXMLDOMNode *node;VARIANT value;nodename_bstr = convert_string_to_bstr("post");IXMLDOMDocument_createElement(xmldoc, nodename_bstr, &elem); // 创建elementSysFreeString(nodename_bstr);IXMLDOMElement_QueryInterface(elem, &IID_IXMLDOMNode, &node); // element转nodeIXMLDOMElement_appendChild(root, node, NULL);// 添加name属性attrname_bstr = convert_string_to_bstr("name");value.bstrVal = convert_string_to_bstr(name);value.vt = VT_BSTR;IXMLDOMElement_setAttribute(elem, attrname_bstr, value);SysFreeString(attrname_bstr);SysFreeString(value.bstrVal);// 添加节点内文本text_bstr = convert_string_to_bstr(text);IXMLDOMElement_put_text(elem, text_bstr);SysFreeString(text_bstr);// 释放element和node对象// 请注意element是node的子类, 换句话说element是一种nodeIXMLDOMElement_Release(elem);IXMLDOMNode_Release(node);
}void write_xml(IXMLDOMDocument *xmldoc)
{IXMLDOMElement *root;create_header(xmldoc);root = create_root(xmldoc);add_post(xmldoc, root, "RPG Maker XP", "RPG Maker XP(RPGXP)是一款可让玩家自行制作在计算机游戏中相当受欢迎的角色扮演游戏,也就是 Role-Playing Game(RPG)的软件。制作完成的游戏,即使在没有安装 RPG Maker XP 的电脑上也能运行。");add_post(xmldoc, root, "高精度的画面", "支持 640×480 像素分辨率 32 色真彩色图像。完全对应 Alpha Channel(每个像素的透明度),光滑的透过处理,柔和的半透明表现。画面的合成方法也增加了通常的半透明合成、加算合成和减算合成。而且字型自动映射,粗体不再引人注目。");add_post(xmldoc, root, "使用软件的音乐播放", "作为 BGM,主要使用 DirectMusic Synthesizer 的 MIDI 播放。因为以软件播放,所以不能用其它格式代替,音乐素材的制造人没必需考虑对各种 MIDI 音乐的对应。在制作过程中能被正常播放的 MIDI 文件,同样可以在其它环境中正常播放。");add_post(xmldoc, root, "灵活且强大的脚本系统", "用 RPGXP 制作完成的游戏,脚本是以 Ruby 语言编写的。预先编写的脚本可以制作十分独特和有趣的游戏,它是为了更高级的游戏制作需求准备的,使用它可以进行画面设计、编写战斗系统,以及一切的游戏要素。运用脚本制作 RPG 以外类型的游戏也是可能的。");add_post(xmldoc, root, "魔塔样板", "魔塔样板是一个用RPG Maker XP、RPG Maker VX、RPG Maker Vx Ace或者VB制作的一个用来制作魔塔的样板,里面有魔塔里一些基本的地图和怪物和各种宝物。制作者只需改动怪物属性和地图,其他的都可以利用复制进行制作,制作起来方便。并且制作者还可以在魔塔样板中进行更高级的操作,做出一些特别的动画或者机关,总之,魔塔样版可以制作一切类型的魔塔。但是,有些质量较差的魔塔样板会有脚本错误。最常用版本是7630。");add_post(xmldoc, root, "房贷利息", "房贷利息是指每个月支付给银行的利息款,计算公式为:剩余未还房款×贷款利率%÷12。若贷款100万元,利率为5.88%,则第一个月要付的利息钱是100万×5.88%÷12=4900元。也就是说“钱价”为4900元/(百万元·月)。");IXMLDOMElement_Release(root);
}// 创建XML文件
void create_xml(const char *name)
{HRESULT hr;IXMLDOMDocument *xmldoc;VARIANT filename;hr = CoCreateInstance(&CLSID_DOMDocument60, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, &xmldoc);if (SUCCEEDED(hr)){write_xml(xmldoc);filename.bstrVal = convert_string_to_bstr(name); // 将char *转换为BSTRfilename.vt = VT_BSTR;hr = IXMLDOMDocument_save(xmldoc, filename);SysFreeString(filename.bstrVal);if (SUCCEEDED(hr))printf("写入XML文件成功\n");elseprintf("写入XML文件失败\n");IXMLDOMDocument_Release(xmldoc);}
}int main()
{CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); // 初始化COM组件对象模型create_xml("myxmlfile.xml");CoUninitialize();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/411117.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Springboot 子工程构建完后无法找到springboot依赖

问题: 构建完子工程后无法找到SpringBootTest 解决方案: 最好用这个构建 https://www.cnblogs.com/he-wen/p/16735239.html 1.先观察项目目录 是否正确 2.观察子工程目录 3.看pom.xml中是否引用springboot依赖 4.检查代码 查看父项目是否包含子模块 查看子模块的父项目是否…

uniapp写微信小程序实现电子签名

写电子签名一定要注意的是一切全部按照手机上的适配来&#xff0c;为啥这么说呢&#xff0c;因为你在微信开发者工具中调试的时候认为是好的&#xff0c;正常的非常nice,当你发布版本的时候你会发现问题出来了。我下边的写法你可以直接用很简单。就是要记住canvas的几个属性和用…

基于SSM的校园闲置物品交易平台设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

教师语言的重要性体现在哪些方面?

教师&#xff0c;这个职业被誉为人类灵魂的工程师&#xff0c;他们的话语有着无可比拟的力量。有时&#xff0c;一句话就能点亮一个孩子的世界&#xff0c;也可以打破一个孩子的求知欲望。那么&#xff0c;教师话语的重要性究竟体现在哪些方面呢&#xff1f; 教师的话语是激发…

帮管家 CRM init 信息泄露漏洞

此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等&#xff08;包括但不限于&#xff09;进行检测或维护参考&#xff0c;未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失&#xff0c;均由使用…

npm换源

检查现在的源地址 npm config get registry 使用淘宝镜像 npm config set registry https://registry.npm.taobao.org 使用官方镜像 npm config set registry https://registry.npmjs.org/

《WebKit 技术内幕》之三(2): WebKit 架构和模块

2.基于 Blink 的 Chrominum 浏览器结构 2.1 Chrominum 浏览器的架构及模块 Chromium也是基于WebKit&#xff08;Blink&#xff09;开发的&#xff0c;并且在WebKit的移植部分中&#xff0c;Chromium也做了很多有趣的事&#xff0c;所以通过Chromium可以了解如何基于WebKit构建浏…

大数据深度学习ResNet深度残差网络详解:网络结构解读与PyTorch实现教程

文章目录 大数据深度学习ResNet深度残差网络详解&#xff1a;网络结构解读与PyTorch实现教程一、深度残差网络&#xff08;Deep Residual Networks&#xff09;简介深度学习与网络深度的挑战残差学习的提出为什么ResNet有效&#xff1f; 二、深度学习与梯度消失问题梯度消失问题…

高斯Hack算法

背景 刷leetcode时&#xff0c;碰到一题需要求解n个bit中选择m个bit的所有组合集&#xff0c;我只想到了递归求解&#xff0c;没啥问题&#xff0c;但是在官方题解中看到了牛逼的方法(Gospers Hack)&#xff0c;故记录一下。 4bit中2个1的情况 0011b0101b0110b1001b1010b1100b…

力扣刷MySQL-第三弹(详细讲解)

&#x1f389;欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克&#x1f379; ✨博客主页&#xff1a;小小恶斯法克的博客 &#x1f388;该系列文章专栏&#xff1a;力扣刷题讲解-MySQL &#x1f379;文章作者技术和水平很有限&#xff0c;如果文中出…

Kylin 安装novnc 远程访问

noVNC可以使用浏览器直接访问服务器&#xff0c;而不需要使用VNC客户端。 1.初始环境 关闭防火墙或允许IP访问本机 2.安装依赖 dnf install -y tigervnc-server git 3.git下载novnc git clone https://github.com/novnc/noVNC.git 4.配置信任证书 openssl req -new -x509 …

循环异步调取接口使用数组promiseList保存,Promise.all(promiseList)获取不到数组内容,then()返回空数组

在使用 vue vant2.13.2 技术栈的项目中&#xff0c;因为上传文件的接口是单文件上传&#xff0c;当使用批量上传时&#xff0c;只能循环调取接口&#xff1b;然后有校验内容&#xff1a;需要所有文件上传成功后才能保存&#xff0c;在文件上传不成功时点击保存按钮&#xff0c…

vscode mysql cmake windows 常见问题和推荐文章

1.在windows中安装mingw64和cmake&#xff08;可查一下网上的安装教程&#xff09;&#xff0c;配置环境变量 2.在vscode中用CMake构建项目的时候&#xff0c;可能会出现这样的问题:“The C compiler identification is unknownn...”,可参考这篇博客 在windows下使用Vscode用…

pyspark笔记:over

1 方法介绍 在 PySpark 中&#xff0c;over 函数是一个非常重要的概念&#xff0c;尤其是在使用窗口函数&#xff08;例如 row_number, rank, dense_rank, lead, lag 等&#xff09;时。over 函数允许你对一个数据集进行分组&#xff0c;然后在每个分组内应用窗口函数。 1.1 …

UE4 添加按键输入事件 并在蓝图中使用按键输入节点

绑定按键 选择Edit/ProjectSettings/Engine/Input 在bindings中可以选择添加ActionMappings或则AxisMappings ActionMappings:按键事件&#xff0c;有按下和抬起两个事件&#xff0c;需要分别用两个键触发AxisMappings:输入事件&#xff0c;返回值为float&#xff0c;对于键盘…

系统架构的演变:从单体到微服务的旅程

文章目录 前言一、单体架构简图 二、垂直架构简图 三、水平架构简图 四、面向服务架构&#xff08;SOA&#xff09;简图 五、微服务架构简图 总结 前言 随着信息技术的快速发展&#xff0c;系统架构也在不断演变。从早期的单体架构到现代的微服务架构&#xff0c;每一次的变革都…

.NET 弹性和瞬时处理库Polly

写在前面 Polly 是一个 .NET 弹性和瞬态故障处理库&#xff0c;允许开发人员以 Fluent 和线程安全的方式来实现重试、断路、超时、隔离和回退策略。 Polly 的七种策略介绍 重试&#xff08;Retry&#xff09;: 当出现故障时自动进行重试断路&#xff08;Circuit-breaker&…

Open3D 点云转深度图像

目录 一、算法原理1、算法过程2、主要函数二、代码实现三、结果展示1、点云2、深度图像四、测试数据Open3D 点云转深度图像由CSDN点云侠原创。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。<

软件测试|使用matplotlib绘制气泡图

简介 气泡图&#xff08;Bubble Chart&#xff09;是一种数据可视化工具&#xff0c;通常用于展示三维数据的分布情况&#xff0c;其中数据点以气泡的形式显示在二维平面上&#xff0c;每个气泡的位置表示两个变量的值&#xff0c;气泡的大小表示第三个变量的值。在Python中&a…

ArcGIS Pro 如何新建布局

你是否已经习惯了在ArcGIS中数据视图和布局视图之间来回切换&#xff0c;到了ArcGIS Pro中却找不到二者之间切换的按钮&#xff0c;即使新建布局后却发现地图怎么却是一片空白。 这一切的一切都是因为ArcGIS Pro的功能框架完全不同&#xff0c;这里为大家介绍一下在ArcGIS Pro…