从XML文件中检索CString文件路径



我有一个包含许多值的XML文件和一个可以检索这些值的工作c++函数

其中两个值是:

  1. 文件路径,如:"C:foo1foo2"
  2. 文件名称:"foo3.txt"

将它们组合在一起,它们将成为"C:foo1foo2foo3.txt"

然而,当试图设置CString来保存文件路径时,它会给出一个错误,因为由于字符串表示法及其与字符的交互作用,在字符串中不允许使用字符

我正在使用MFC,我知道WIN32允许您使用/而不是创建文件路径,因此:"C:/foo1/foo2/foo3.txt"可以工作。我在Windows资源管理器中测试了一下,效果不错。

我想从XML文件中收集文件路径,但是当它进来时,它将在其文件路径中具有而不是/,这意味着它将无法替换字符(进入的字符串将由于XML没有字符的问题而产生错误)。

如何安全地检索路径作为CString,理想情况下,同时将任何字符转换为/字符。

现在我不熟悉"CString"你所指的类。谷歌的API文档只有标准的c风格的字符数组格式命令,所以我将假设正确或错误的cstring是一个字符数组。

我们需要使用一个不可调整大小的对象,这意味着我们要么

  1. 需要使用堆,这将是缓慢的,并且可能会泄漏内存,如果内存不删除以后
  2. 允许字符串的最大长度,如果小于此值,将被截断。

堆示例(注:我不使用智能指针作为我假设他们无法访问,你刚刚std:: string,而不是这样做。)

char* escapeString(const char* data, unsigned int length){
//multiplying by 1.5 means this could still truncate, 
//but I'm making an educated guess it's not all bad characters.
const int newLen = (length + 1) * 1.5;
char* escaped = new char[newLen + 1];

unsigned int index = 0;
for(unsigned int i = 0; i < length && i < newLen; i++){
if(data[i] == '\' || data[i] == '"'){
escaped[index++] = '\';
}
else if(data[i] == '%'){
escaped[index++] = '%';
}
//else anything else you want to escape
escaped[index++] = data[i];
}
//Make sure a null string is null terminatedescaped
escaped[index] = '';
return escaped;
}

int main() {
const char* stringWithBadChars = "I"m not a %%good \string";

char* escapedString = escapeString(stringWithBadChars, strlen(stringWithBadChars));
std::cout << escapedString;
delete [] escapedString;
return 0;
}

如果我们在堆栈上这样做,它会快得多,但是我们受到我们提供的缓冲区大小的限制,以及函数中缓冲区的大小。如果其中一个失败,则返回bool值。

bool escapeString(char* data, unsigned int length){
const int newLen = 1000;
char escaped[1001];

unsigned int index = 0;
for(unsigned int i = 0; i < length && i < newLen; i++){
if(data[i] == '\' || data[i] == '"'){
escaped[index++] = '\';
}
else if(data[i] == '%'){
escaped[index++] = '%';
}
escaped[index++] = data[i];
}
//Make sure a null string is null terminatedescaped
memcpy(data, escaped, index);
escaped[index] = '';
return index < length && index < 1000;
}

使用memmov而不是逐个字符地复制它可能会获得更高的效率。这样做,你也不需要第二个字符数组。

CString保留了一些特殊字符。以Format命令为例。链接的文档指向:格式规范语法:printfwprintf函数。

如注释所述,表示特殊字符。例如:

  • t将插入选项卡性格。
  • "将插入双引号性格。

所以当它到达时,它期望下一个字符是特殊字符之一。因此,当您真正需要反斜杠时,您可以使用\.

链接的文章确实解释了%,但没有斜杠。然而,它与%完全相同,因为它也有特殊的含义。因此,当您需要百分号时,可以使用%%