C++/CLI中如何将XmlTextReader读取的字符串存入变量或vector
问题原因
你当前使用的是C++/CLI混合编译模式,XmlTextReader属于.NET托管类,reader->Value返回的是托管堆上的System::String^类型,和你代码中定义的原生C++类型std::string、std::vector<std::string>不存在隐式转换,直接传参、赋值必然触发类型不匹配编译错误。
你之前注释掉的几种写法全部存在基础错误:
entries.insert/push_back(reader->Value):托管字符串无法直接转为原生std::stringmyText = Console::WriteLine(reader->Value):Console::WriteLine返回值为void,不支持赋值给变量myText = reader->Value:同样是托管到原生类型无隐式转换的问题
另外你当前的节点遍历逻辑也存在游标错乱问题:在XmlNodeType::Element分支中调用ReadToFollowing会直接移动读取游标到匹配节点,跳过外层Read()循环遍历到的其他节点,属性遍历中反复调用GetAttribute("TITLE")也会导致属性读取重复/漏读。
修复步骤
- 引入C++/CLI官方提供的类型封送头文件,用于托管字符串和原生字符串的转换:
#include <msclr/marshal_cppstd.h>
- 修正节点遍历逻辑,不要在主读取循环中随意调用会移动游标的方法,属性遍历完成后要把游标移回当前元素节点。
- 读取到
Text节点的Value后,先通过封送方法转为原生std::string,再存入vector或赋值给原生字符串变量。
修复后核心代码
#include "pch.h" #include <iostream> #include <fstream> #include <algorithm> #include <vector> #include <string> #include <tchar.h> #include <msclr/marshal_cppstd.h> // 新增:托管/原生类型转换头文件 #using <System.Xml.dll> #using <System.Windows.Forms.dll> #using <mscorlib.dll> using namespace std; using namespace System; using namespace System::Xml; using namespace msclr::interop; // 新增:简化marshal_as调用 int main() { string myText = ""; vector<string> entries = { "DeTal" }; entries.push_back("Fulano");//test purposes // 推荐用XmlReader::Create代替直接构造XmlTextReader,符合微软官方规范,不影响现有逻辑 XmlReader^ reader = XmlReader::Create("C:\\Users\\你的文件路径.xml"); while (reader->Read()) { switch (reader->NodeType) { case XmlNodeType::Element: Console::Write("<{0}", reader->Name); // 正确遍历当前元素所有属性 while (reader->MoveToNextAttribute()) { Console::Write(" {0}='{1}'", reader->Name, reader->Value); // 如需存储属性值,同样转成原生string即可 // std::string attrValue = marshal_as<std::string>(reader->Value); // entries.push_back(attrValue); } Console::WriteLine(">"); reader->MoveToElement(); // 游标移回当前元素,避免影响后续读取 break; case XmlNodeType::Text: Console::WriteLine(reader->Value); // 核心修复:托管String^转原生std::string后再存储 myText = marshal_as<std::string>(reader->Value); entries.push_back(myText); break; case XmlNodeType::EndElement: Console::Write("</{0}", reader->Name); Console::WriteLine(">"); break; } } reader->Close(); // 用完记得释放reader资源 cout << "\nPress enter to start sort: "; Console::ReadLine(); // 后续排序逻辑直接操作entries vector即可 return 0; }
注意:如果你的XML文件路径包含中文字符,确认文件编码和路径字符串格式匹配,避免出现文件读取失败问题。
内容的提问来源于stack exchange,提问作者anonymousGuy
相关产品推荐
相关产品推荐

