visual如何比较C++程序中两个特定字符之间的两个文件中的文本行



我正在编写一个程序,它可以清理xml文件,并从txt文件向设置部分添加新行。部分代码中有一个标记为//部分的部分。这是在该部分期间或之后,两者都可以,我想比较这些行,以确保它们没有重复,但在这种情况下忽略它们的设置True和False,如果其中一个设置为True,另一个设为False,则认为它们相同,只保留第二行并丢弃第一行。以下是设置外观的示例:

<setting1>true</setting1>
<setting2blue>false</setting2blue>
<setting3>true</setting3>
<setting1>false</setting1>
<setting4>true</setting4>
<setting2blue>true</setting2blue>

所以最后,我希望第一个设置1被移除,第二个设置1保持不变,设置2也是如此。请记住,这是一个例子,因为设置有不同的名称,有时包含相同的单词。

我试过使用.compare,但由于我对C++还很陌生,所以真的迷失了方向。尽管我可能需要做一个新的流入和流出,然后在我之前的工作完成后进行比较,但我仍然对如何进行比较感到困惑。

我感谢你的帮助。

谢谢,Vendetto

这是我在不需要运行整个程序的情况下进行测试的程序的一部分。

#include <stdio.h>
#include <fstream>
#include <sstream>
#include <iostream>
#include <string>
#include <cctype>
#include <cstdlib>
#include <set>
#include <vector>
#include <algorithm>
#include <cassert>
#include <Windows.h>
using namespace std;

bool isSpace(unsigned char c) {
return ( c == 'r' ||
c == 't' || c == 'v' || c == 'f');
}

int main()
{

const string Dir{ "C:/synergyii/config/" };
ifstream in_config{ Dir + "clientconfig.xml" },
in_newlines{ Dir + "newlines.txt" };
ofstream out{ Dir +  "cltesting.txt" };

vector<string> vlines31;
vector<string> vlines32;
set<string>    slines31;
set<string>    slines32;

for (string line31; getline(in_config, line31); vlines31.push_back(line31))
if (line31.find("<settings>") != string::npos) {
vlines31.push_back(line31);
break;
}

for (const auto& v : vlines31)
out << v << 'n';

// <settings> Part

for (string line32; getline(in_config, line32) && line32.find("</settings>") == string::npos; ) {
line32.erase(remove_if(line32.begin(), line32.end(), isSpace), line32.end());
line32.erase(line32.find_last_not_of(" ") + 1);
const auto& result = slines32.insert(line32);
if (result.second)
vlines32.push_back(line32);
}

for (string line32; getline(in_newlines, line32);) {
line32.erase(remove_if(line32.begin(), line32.end(), isSpace), line32.end());
const auto& result = slines32.insert(line32);
if (result.second)
vlines32.push_back(line32);
}

vlines32.erase(unique(vlines32.begin(), vlines32.end()), vlines32.end() );

for (auto it = vlines32.cbegin(); it != vlines32.cend(); ++it)
out << 't' << 't' << *it << 'n';

out << 't' << "</settings>n";
out << "</config>n";

in_config.close();
out.close();
}

关于XML的注意事项第一:

XML允许格式化,而不必改变其内容的含义。除了缩进之外,元素可以写在一行中,也可以分布在多行中。甚至可以在一行中写入整个XML文件(假设元素的内容中没有换行符,就像在OP的情况下一样(。

使用C++标准I/O正确读取XML比使用几个std::getline()s更复杂。要做到这一点,应该使用XML库将XML文件读取到DOM中以进行预期的处理
例如SO:我应该在C++中使用什么XML解析器提供了有关可用XML库的概述。


也就是说,我想演示一个可能的解决方案,但使用另一个更简单的配置。format–用冒号(:(分隔的键值对。

如何过滤出重复的密钥:

解决方案实际上很简单:
将整个文件逐行读取到strings的vector中。
如果一行包含密钥,则密钥存储在查找表中
如果关键字已在该查找表中,则前一次出现(行(将被标记为无效。为了简单起见,我只是划清界限。如果空行可能是有效内容(应保存在文件中(,则应使用其他内容来注释该行,例如每行存储一个额外的bool
我没有考虑删除行,因为这会使后面行的所有键的存储行索引无效(或者我必须遍历查找表来修复它们(。

演示:

#include <iostream>
#include <map>
#include <sstream>
#include <string>
#include <vector>
std::vector<std::string> lines;
using LookUpTable = std::map<std::string, size_t>;
LookUpTable lut;
std::istream& readLine(std::istream &in)
{
std::string line; if (!std::getline(in, line)) return in;
const size_t iLine = lines.size();
// extract key
const size_t i = line.find(':');
if (i < line.size()) { // Has the line a key at all?
std::string key = line.substr(0, i);
// look whether there was already this setting
const LookUpTable::iterator iter = lut.find(key);
if (iter != lut.end()) { // Was it already there?
// clear previous line
lines[iter->second].clear();
}
// store key and line index
lut.emplace(std::move(key), iLine);
}
// store line in lines buffer
lines.push_back(std::move(line));
// done
return in;
}
void readFile(std::istream &in)
{
while (readLine(in));
}
void writeFile(std::ostream &out)
{
for (const std::string line : lines) {
// skip empty lines
if (line.empty()) continue;
// write non-empty lines
out << line << 'n';
}
}
int main()
{
std::string sample = R"(# sample config file
setting1: true
setting2blue: false
setting3: true
setting1: false
setting4: true
setting2blue: true
)";
// read the sample
{ std::istringstream in(sample);
readFile(in);
}
// write the sample (with clean-up)
std::cout << "Output:n";
writeFile(std::cout);
}

输出:

Config.:
# sample config file
setting3: true
setting1: false
setting4: true
setting2blue: true

coliru上的实时演示

硝酸盐提取:

无序地图可能提供比地图更快的查找速度。它可能会以更高的内存足迹来支付这笔费用。我怀疑这种差异是否对任务至关重要,但只要进行最小的更改,它也适用于unordered_map

coliru上的实时演示

最新更新