私のソースコードを見て、私のコメントが実際のアルゴリズムを正確に説明していないことに気付きました。そのため、私が代わりに働いてサンプルを提供します。当社のソフトウェアは、移植を意図していると
original: \folder1\..\folder1\file.dat
resolved: folder1/file.dat
original: \folder1\folder2\..\..\folder1\file.dat
resolved: folder1/file.dat
original: \folder1\folder3\..\folder2\..\folder1\file.dat
resolved: folder1/folder1/file.dat
original: \.\folder1\..\folder1\file.dat
resolved: folder1/file.dat
original: folder1\..\folder1\.\file.dat
resolved: folder1/file.dat
は、我々はディレクトリの区切りとして/
を好む
:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void strTok(const string &text, char delim, vector<string> &tokens)
{
for (size_t i = 0, j, n = text.size(); i < n; i = j) {
while (i < n && text[i] == delim) ++i;
j = text.find(delim, i);
if (j > n) j = n;
tokens.push_back(text.substr(i, j - i));
}
}
string filePathResolve(string filePath)
{
// make paths Unix-style
for (char &c : filePath) if (c == '\\') c = '/';
// consider UNC paths
const char *root = "";
if (filePath.length() >= 2 && filePath.compare(0, 2, "//") == 0) {
root = "//"; filePath.erase(0, 2);
}
// split file path into list
vector<string> list; strTok(filePath, '/', list);
// remove all non-functional entries (occurrences of '//' and '/.')
for (size_t i = list.size(); i--;) {
if (list[i].empty() || list[i] == ".") list.erase(list.begin() + i);
}
for (size_t i = 1; i < list.size(); ++i) {
if (list[i] == ".." && list[i - 1] != "..") {
list.erase(list.begin() + i - 1, list.begin() + i + 1);
i -= 2;
}
}
// rebuilt path from list
filePath = root;
if (list.size()) {
filePath += list.front();
for (size_t i = 1, n = list.size(); i < n; ++i) {
(filePath += '/') += list[i];
}
}
// done
return filePath;
}
int main()
{
string samples[] = {
"\\folder1\\..\\folder1\\file.dat",
"\\folder1\\folder2\\..\\..\\folder1\\file.dat",
"\\folder1\\folder3\\..\\folder2\\..\\folder1\\file.dat",
"\\.\\folder1\\..\\folder1\\file.dat",
"folder1\\..\\folder1\\.\\file.dat"
};
for (string path : samples) {
cout << "original: " << path << endl
<< "resolved: " << filePathResolve(path) << endl;
}
// done
return 0;
}
は、Windows 10(64ビット)上でVS2013でテスト。しかしながら、これは逆の方向に作用するように容易に適合させることができ、即ち最初に/
を\\
で置き換え、後者を排他的に使用する。
IMHO、最も重要な部分はUNC pathsです。私たちの運については、顧客はそれをもっと少なく理解しているようです。少なくとも、私はこれについて(何年も)何の苦情も受けていませんでした。
上記のリンク先のWikipediaの記事を読んで、URLも記載されていることに気付きました。 このアルゴリズムではURLが正しく処理されません。
「\ f」はフォームフィードです。毎回 '\\ f'を使うつもりです。 –
テキスト置換をしたいのですか、 'folder2'と' folder3'が存在することを検証する必要がありますか?システムは名前を検証しますが、それはプレーンなテキスト置換よりも多くの作業になります。この作業を行うためのMicrosoft API関数がある可能性は非常に高いです。私は、コードのUNIX類似物を持っていることを知っています。プレーンテキストの置換と検証の両方がありますが、検証コードは名前が存在するかどうかだけではなく、シンボリックリンクも処理します。 (指定された文字列はすべて文字列リテラルなので、その場でそれらを確実に変更することはできません)。 –
私は '\\'訂正をお願いします!これらのフォルダがすべて存在すると仮定しているので、テキスト置換を行いたいと思います。これらのMicrosoft APIの機能は何ですか? (私はシンボリックリンクを扱わないことを前提としていますが、それらを処理する方がより良いでしょう) – Ryan