作者jayzhuang (Jay)
看板C_and_CPP
标题[问题] C++ 储存XML多笔资料的问题
时间Tue Aug 20 14:37:33 2019
开发平台(Platform): (Ex: Win10, Linux, ...)
Win10
编译器(Ex: GCC, clang, VC++...)+目标环境(跟开发平台不同的话需列出)
vs2019
额外使用到的函数库(Library Used): (Ex: OpenGL, ...)
问题(Question):
上次感谢大家提醒我透过secedit转档的格式,改成ini;
并使用ini parser,让我找到:GetPrivateProfileString/WritePrivateProfileString
目前我的Pwdword.ini,可透过这两个去做读取後,再存入到XML格式的档案中。
但是我一个奇怪状况,之前明明可以直接在显示多笔资料的,
现在显示却永远都显示最後一笔资料.....
喂入的资料(Input):
我将Pwdword.ini内,三个项目等号的资料透过GetPrivateProfileString,
取得之後,一个一个测试,确认有资料入:
(下图为Pwdword.ini的内容,红色框框圈起三个资料是我抓取的)
https://imgur.com/PALPOII
下列程式码是三笔资料的格式转档後,透过程式码给储存xml的Function
Sleep(10000);
//把要回传的LGPO_xml细项内容储存到这
string LGPO_XML_FilePath = GetFilePath() + "LGPO_Item.xml";
//写入LGPO项目的内容
Save_LGPO_Item LGPO_Item_Content;
LGPO_Item_Content.LGPO_class = 1;
char Pw01[] = "MinimumPasswordAge";
char Pw02[] = "MaximumPasswordAge";
char Pw03[] = "MinimumPasswordLength";
char Pw04[] = "PasswordComplexity";
char Pw05[] = "PasswordHistorySize";
char Pw06[] = "ClearTextPassword";
char Pw07[] = "LockoutBadCount";
char Pw08[] = "LockoutDuration";
char Pw09[] = "ResetLockoutCount";
char Pw10[] = "ForceLogoffWhenHourExpire";
char Pw11[] = "NewAdministratorName";
char Pw12[] = "NewGuestName";
//宣告要资料类型名称与,透过GetPrivateProfileString去抓取名称後面的资料
CString MinimumPasswordAge_value;
::GetPrivateProfileString(_T("System Access"), _T("MinimumPasswordAge"), 0, MinimumPasswordAge_value.GetBuffer(MAX_PATH), MAX_PATH, _T("C:\\LGPO\\Pwdword.ini"));
MinimumPasswordAge_value.ReleaseBuffer();
//之後要把CString 转成string的资料类型,方可回传。
std::string MinimumPasswordAge_string(CW2A(MinimumPasswordAge_value.GetString()));
CString MaximumPasswordAge_value;
::GetPrivateProfileString(_T("System Access"), _T("MaximumPasswordAge"), 0, MaximumPasswordAge_value.GetBuffer(MAX_PATH), MAX_PATH, _T("C:\\LGPO\\Pwdword.ini"));
MaximumPasswordAge_value.ReleaseBuffer();
std::string MaximumPasswordAge_string(CW2A(MaximumPasswordAge_value.GetString()));
CString NewAdministratorName_value;
::GetPrivateProfileString(_T("System Access"), _T("NewAdministratorName"), 0 , NewAdministratorName_value.GetBuffer(MAX_PATH),MAX_PATH, _T("C:\\LGPO\\Pwdword.ini"));
NewAdministratorName_value.ReleaseBuffer();
std::string NewAdministratorName_string(CW2A(NewAdministratorName_value.GetString()));
LGPO_Item_Content.Item_name = Pw01;
LGPO_Item_Content.Item_value = MinimumPasswordAge_string;
LGPO_Item_Content.Item_name = Pw02;
LGPO_Item_Content.Item_value = MaximumPasswordAge_string;
LGPO_Item_Content.Item_name = Pw11;
LGPO_Item_Content.Item_value = NewAdministratorName_string;
Save_LGPO_XML(&LGPO_Item_Content, LGPO_XML_FilePath);
预期的正确结果(Expected Output):
(下图是三笔资料的显示)
https://imgur.com/c6CvK5k
错误结果(Wrong Output):
(结果永远都只有一笔)
https://imgur.com/OvhZGsW
程式码(Code):(请善用置底文网页, 记得排版,禁止使用图档)
这是我把资料存入XML的Funcion,我把回传值得Function与Save_XML的Function分开两种
--------------------回传值的Funcion-------------------------
//宣告XML资料型别,是要传入的值
class Save_LGPO_Item
{
public:
int LGPO_class; //本机群组原则类别的代号:(1)安全性设定-密码原则
string Item_name; //细项的名称
string Item_value; //细项的设定值
};
---------------------------------------------------------------
------------------存入XML的Function---------------------------
void Save_LGPO_XML(Save_LGPO_Item*LGPO_Item,string file)
{
//建立一个XML的文件物件
TiXmlDocument* LGPO_Document = new TiXmlDocument();
//XML档案格式
TiXmlDeclaration* LGPO_Decl = new TiXmlDeclaration("1.0", "UTF-8", "yes");
//写入第一行XML的资料格式
LGPO_Document->LinkEndChild(LGPO_Decl); // <?xml version="1.0" encoding="UTF-8"?>
//建立一个根元素并连线
TiXmlElement* RootElement = new TiXmlElement("Root");
LGPO_Document->LinkEndChild(RootElement);
//建立第一个节点LGPO元素并连线
TiXmlElement* LGPO_Element = new TiXmlElement("LGPO");
RootElement->LinkEndChild(LGPO_Element);
//设定第一个节点LGPO元素的属性
LGPO_Element->SetAttribute("class", LGPO_Item->LGPO_class);
//建立子节点:Item项目,以及属性内的:名称、数值 ,并连线
TiXmlElement* ItemElement = new TiXmlElement("Item");
LGPO_Element->LinkEndChild(ItemElement);
ItemElement->SetAttribute("name", LGPO_Item->Item_name.c_str());
ItemElement->SetAttribute("value", LGPO_Item->Item_value.c_str());
//建立xml文件,并把项目存入
LGPO_Document->SaveFile(file.c_str());
}
补充说明(Supplement):
PS:我自己额外写的直接把资料丢入到我写的Save_XML 的Function
上星期测试明明会有显示,但现在连这方法都不行了....
搞不懂为什麽? 是我修改的时候,删除到某段程式码? 还是我少做了什麽?
//把要写入的LGPO_xml细项内容储存到这
string LGPO_XML_FilePath = GetFilePath() + "LGPO_Item.xml";
//写入LGPO项目的内容
Save_LGPO_Item LGPO_Item_Content;
LGPO_Item_Content.LGPO_class = 1;
LGPO_Item_Content.Item_name = "MinimumPasswordAge";
LGPO_Item_Content.Item_value = 1;
LGPO_Item_Content.Item_name = "MaximumPasswordAge";
LGPO_Item_Content.Item_value = 90;
https://imgur.com/CQ4BMVS
希望有人能帮我看看是我缺少了什麽吗?
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 218.161.102.123 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1566283055.A.1EE.html
1F:→ firejox: 不宣告3个吗? 08/20 17:14
因为我要储存的资料是2个以上(甚至10~100个都有可能)
但我现在连2~3个都无法显示.... 所以才再找我Save_XML的Function问题在哪....
※ 编辑: jayzhuang (218.161.102.123 台湾), 08/20/2019 18:07:14
2F:→ firejox: 你TiXmlElement("Item")只有1个,传入的也只有1个 08/20 19:09
3F:→ firejox: 当然显示一个 08/20 19:09
这样啊.... 那该怎麽改压? 因为我想要的是
Item资料来多少,它就会一直逐一往下新增。
要宣告一个Data变数好像也不对,因为资料量客户那边无法估计多少
我这边用12个只是预设的.....
※ 编辑: jayzhuang (218.161.102.123 台湾), 08/20/2019 19:23:38
4F:嘘 joechen1008: 伸手牌? 08/20 23:45
5F:→ firejox: 你要传多个,用阵列或stl container 都行 08/21 00:01
请问,用阵列或STL,那是要放在Save_XML的Function?
还是要放在主页写资料那边好?
(研究整个早上@@.....还没搞懂....)
※ 编辑: jayzhuang (218.161.102.123 台湾), 08/21/2019 12:41:52
6F:→ firejox: 都说传多个了,放在Save_XML没意义 08/22 01:56
我觉得应该是我Save_XML的Function无法做一次存取全部的值.....
我可能要再改一次.....
Vector的方式我大致上了解,但我得要想想的问题
(1)如何回传全部的数值
(2)可以让数值作全部储存,或是连续存取/复写
※ 编辑: jayzhuang (218.161.102.123 台湾), 08/23/2019 11:54:08