-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathmain.cpp
135 lines (108 loc) · 4.51 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include <iostream>
#include <string>
#include <sstream>
#include <regex>
#include <cstdlib>
#include <cstring>
enum CopyType : unsigned short int {
FromSameFolder,
FromAnotherFolder
};
template<typename T, size_t N>
size_t ArraySize(T(&)[N]) {
return N;
}
std::string files[] = {
"example.txt"
// Что происходит при copy-paste одного и того же файла в одной и той же папке:
, "example — копия.txt"
, "example — копия 2.txt"
, "example — копия 4.txt"
, "example — копия 40.txt"
, "example — копия 100.txt"
, "example — копия 100500.txt"
// Что происходит при copy-paste файла из другой папки в папку, где уже есть
// файл с таким именем:
, "example 2.txt"
, "example 3.txt"
, "example 5.txt"
, "example 40.txt"
, "example 100.txt"
, "example 100500.txt"
, "another.txt"
, "two.txt"
, "two — копия.txt"
, "t 3.txt"
// Скопировать example.txt два раза в одной папке.
// Скопировать example — копия 2.txt в другую папку.
// Скопировать обратно.
, "example — копия 2 2.txt"
, "b копия 2.txt"
, "b копия 2 2.txt"
};
std::string GetExtensionFromFileName(const std::string &filename) {
size_t lastdot = filename.find_last_of(".");
if (lastdot == std::string::npos)
return "";
return filename.substr(lastdot);
}
std::string RemoveExtensionFromFileName(const std::string &filename) {
size_t lastdot = filename.find_last_of(".");
if (lastdot == std::string::npos)
return filename;
return filename.substr(0, lastdot);
}
template<size_t N>
bool Exists(std::string filename, std::string (&filelist)[N]) {
for (size_t i = 0; i < N; ++i)
if (filename == filelist[i])
return true;
return false;
}
template<size_t N>
std::string MakeFileName(std::string filename, std::string (&filelist)[N], CopyType type) {
static const std::regex PATTERN_DUPLICATE(R"(^(.* — копия)( ?)(\d*)$)");
static const std::regex PATTERN_COPY(R"(^(.*?)( ?)(\d*)$)");
const std::regex &pattern = type == FromSameFolder ? PATTERN_DUPLICATE : PATTERN_COPY;
std::smatch match;
std::string ext = GetExtensionFromFileName(filename);
std::string resultname = RemoveExtensionFromFileName(filename);
if (Exists(filename, filelist)) {
if (type == FromAnotherFolder) {
resultname += " 2";
} else if (type == FromSameFolder) {
if (!std::regex_search(resultname, match, pattern)) {
resultname += " — копия";
}
}
} else {
return filename;
}
int i = 2;
while (Exists(resultname + ext, filelist)) {
if (std::regex_search(resultname, match, pattern)) {
const std::string num = match[3];
if (!num.empty()) ++i;
std::stringstream replace;
replace << "$1 " << i;
resultname = std::regex_replace(resultname, pattern, replace.str());
}
}
return resultname + ext;
}
int main(int argc, const char * argv[]) {
std::cout << "" << std::endl;
assert("example — копия 3.txt" == MakeFileName("example.txt", files, FromSameFolder));
assert("example — копия 3.txt" == MakeFileName("example — копия 3.txt", files, FromSameFolder));
assert("example — копия 3.txt" == MakeFileName("example — копия 4.txt", files, FromSameFolder));
assert("unique.txt" == MakeFileName("unique.txt", files, FromSameFolder));
assert("another — копия.txt" == MakeFileName("another.txt", files, FromSameFolder));
assert("two — копия 2.txt" == MakeFileName("two.txt", files, FromSameFolder));
assert("t 3 2.txt" == MakeFileName("t 3.txt", files, FromAnotherFolder));
assert("example — копия 2 2 — копия.txt" == MakeFileName("example — копия 2 2.txt", files, FromSameFolder));
assert("example — копия 2 2 2.txt" == MakeFileName("example — копия 2 2.txt", files, FromAnotherFolder));
assert("b копия 2 3.txt" == MakeFileName("b копия 2.txt", files, FromAnotherFolder));
assert("example 4.txt" == MakeFileName("example.txt", files, FromAnotherFolder));
assert("example 5 2.txt" == MakeFileName("example 5.txt", files, FromAnotherFolder));
return EXIT_SUCCESS;
}