我正在使用C++/CLI在Visual Studio2008中构建一个程序,我一直试图将我的默认用户目录设置保存在一个txt文件中。到目前为止,我设法将它保存在txt文件中,如下所示。
Input Directory=C:\Input
Output Directory=C:\Output问题是,我的程序如何检测单词"Input Directory=“并只接受它后面的单词呢?
有没有办法在文本文件中搜索特定的单词,并在C++/CLI中替换它?例如,我可以搜索"C:\Input“并将其替换为"D:\Input”。
发布于 2012-05-09 01:06:14
经过一天的努力寻找简单的解决方案后,我决定省略@Hans Passant建议的"Input Directory =“,并做一个粗略的变通方法,使用类似于this的技术,将第一行读取为输入,第二行读取为输出文件夹设置。
感谢所有回复的人。
发布于 2012-05-07 23:17:42
您可以通过多种方式读取文件。使用c++\cli的好处之一是您可以利用非常简洁的.net接口。
因此,您可以使用File::ReadAllLines,然后扫描每一行以查找字符串"Input Directory“
发布于 2012-05-07 23:30:25
我认为它是一种类似INI的语法,但没有节,为了解析它,需要执行以下操作。
在将用于解析文件的类的构造函数中(例如):
Dictionary<string, string>,您将在其中保留已解析的值(为键指定一个不区分大小写的比较器)。在GetValue()方法中执行以下操作:
这是一个简单的INI解析器的可能实现(如果您不需要节名称,只需为其传递一个空字符串)。
using namespace System;
using namespace System::Text;
using namespace System::IO;
using namespace System::Globalization;
using namespace System::Collections::Generic;
namespace Testy
{
ref class IniParser
{
public:
IniParser()
{
_values = gcnew Dictionary<String^, Dictionary<String^, String^>^>(
StringComparer::InvariantCultureIgnoreCase);
}
IniParser(String^ path)
{
_values = gcnew Dictionary<String^, Dictionary<String^, String^>^>(
StringComparer::InvariantCultureIgnoreCase);
Load(path);
}
void Load(String^ path)
{
String^ currentSection = "";
for each (String^ line in File::ReadAllLines(path))
{
if (String::IsNullOrWhiteSpace(line))
continue;
if (line->StartsWith(L";", StringComparison::InvariantCultureIgnoreCase))
continue;
if (line->StartsWith(L"[", StringComparison::InvariantCultureIgnoreCase) && line->EndsWith(L"]", StringComparison::InvariantCultureIgnoreCase))
{
String^ sectionName = line->Substring(1, line->Length - 2);
if (String::IsNullOrWhiteSpace(sectionName))
continue;
currentSection = sectionName;
}
array<String^>^ parts = line->Split(gcnew array<wchar_t>(2) { '=' }, 2);
if (parts->Length == 1)
SetString(currentSection, parts[0]->Trim(), "");
else
SetString(currentSection, parts[0]->Trim(), parts[1]->Trim());
}
}
bool ContainsSection(String^ sectionName)
{
return _values->ContainsKey(sectionName);
}
bool ContainsValue(String^ sectionName, String^ valueName)
{
Dictionary<String^, String^>^ values = GetSection(sectionName);
if (values == nullptr)
return false;
return values->ContainsKey(valueName);
}
void Clear()
{
_values->Clear();
}
void SetString(String^ sectionName, String^ valueName, String^ value)
{
Dictionary<String^, String^>^ values = GetSection(sectionName);
if (values == nullptr)
{
values = gcnew Dictionary<String^, String^>(StringComparer::InvariantCultureIgnoreCase);
_values->Add(sectionName, values);
}
if (values->ContainsKey(valueName))
values[valueName] = value;
else
values->Add(valueName, value);
}
String^ GetString(String^ sectionName, String^ valueName, String^ defaultValue)
{
Dictionary<String^, String^>^ values = GetSection(sectionName);
if (values == nullptr)
return defaultValue;
if (values->ContainsKey(valueName))
return values[valueName];
return defaultValue;
}
private:
Dictionary<String^, Dictionary<String^, String^>^>^ _values;
Dictionary<String^, String^>^ GetSection(String^ sectionName)
{
if (_values->ContainsKey(sectionName))
return _values[sectionName];
return nullptr;
}
};
}您应该添加错误检查,并且可以省略不需要的部分(例如,节和注释)。要“读取”不同的值类型,可以实现更多的GetXYZ()方法来将GetString()的结果解析为所需的值(例如,float )。
另一种解决方案是通过to...simply导入本地函数来解析INI。它们工作得很好!
https://stackoverflow.com/questions/10484550
复制相似问题