Last active
August 10, 2020 15:30
-
-
Save jin-x/cdd641d98887524b091fb1f82a68717d to your computer and use it in GitHub Desktop.
ArgvToCommandLine
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <string> | |
#include <vector> | |
#include <windows.h> | |
std::string ArgvToCommandLine(int argc, const char** argv) | |
{ | |
std::string result; | |
for (int i = 0; i < argc; ++i) { | |
std::string temp = argv[i]; | |
bool add_qu = (temp.find_first_of(" \t") != std::string::npos), found; | |
// Add slash (\) before double quotes (") and duplicate slashes before it (and at the end of string if whitespace chars are present) | |
auto pos = temp.find('"'); | |
while ((found = (pos != std::string::npos)) || add_qu) { | |
int cnt = found; | |
if (!found) { pos = temp.size(); } | |
while (pos > 0 && temp[pos-1] == '\\') { ++cnt, --pos; } | |
temp.insert(pos, cnt, '\\'); | |
if (!found) { break; } | |
pos = temp.find('"', pos + cnt * 2); | |
} | |
// Add quotes around string if whitespace chars are present | |
if (add_qu) { temp = '"' + temp + '"'; } | |
// Add space delimiter | |
if (i > 0) { result.push_back(' '); } | |
result.append(temp); | |
} | |
return result; | |
} | |
std::string ArgvToCommandLine(std::vector<const char*> str_vec) | |
{ | |
return ArgvToCommandLine(str_vec.size(), str_vec.data()); | |
} | |
std::wstring ArgvToCommandLineW(int argc, const wchar_t** argv) | |
{ | |
std::wstring result; | |
for (int i = 0; i < argc; ++i) { | |
std::wstring temp = argv[i]; | |
bool add_qu = (temp.find_first_of(L" \t") != std::wstring::npos), found; | |
// Add slash (\) before double quotes (") and duplicate slashes before it (and at the end of string if whitespace chars are present) | |
size_t pos = temp.find(L'"'); | |
while ((found = (pos != std::wstring::npos)) || add_qu) { | |
int cnt = found; | |
if (!found) { pos = temp.size(); } | |
while (pos > 0 && temp[pos-1] == L'\\') { ++cnt, --pos; } | |
temp.insert(pos, cnt, L'\\'); | |
if (!found) { break; } | |
pos = temp.find(L'"', pos + cnt * 2); | |
} | |
// Add quotes around string if whitespace chars are present | |
if (add_qu) { temp = L'"' + temp + L'"'; } | |
// Add space delimiter | |
if (i > 0) { result.push_back(L' '); } | |
result.append(temp); | |
} | |
return result; | |
} | |
std::wstring ArgvToCommandLineW(std::vector<const wchar_t*> str_vec) | |
{ | |
return ArgvToCommandLineW(str_vec.size(), str_vec.data()); | |
} | |
int main(int argc, const char** argv) | |
{ | |
//* | |
const char* argv1[] = { | |
"test.exe", | |
"C:\\Program Files\\", | |
"normal\\", | |
"a\ttab", | |
"quote\"mark", | |
"\\\\\\\"", | |
" \" ", | |
"\"quote\\\"\"\ttab \\space\\\\\"" | |
}; | |
const int argc1 = sizeof(argv1)/sizeof(*argv1); | |
argv = argv1; | |
argc = argc1; | |
//*/ | |
std::cout << std::endl << ">> Source arguments:" << std::endl; | |
for (int i = 0; i < argc; ++i) { | |
std::cout << '[' << argv[i] << ']' << std::endl; | |
} | |
std::cout << std::endl << ">> ArgvToCommandLine:" << std::endl; | |
std::string cmdline = ArgvToCommandLine(argc, argv); | |
std::cout << '[' << cmdline << ']' << std::endl; | |
std::cout << std::endl << ">> CommandLineToArgvW:" << std::endl; | |
int argcW; | |
std::wstring cmdlineW(cmdline.cbegin(), cmdline.cend()); | |
wchar_t** argvW = CommandLineToArgvW(cmdlineW.c_str(), &argcW); | |
bool correct = (argc == argcW); | |
for (int i = 0; i < argcW; ++i) { | |
std::wcout << L'[' << argvW[i] << L']' << std::endl; | |
if (correct) { | |
std::wstring argW = argvW[i]; | |
std::string arg(argW.cbegin(), argW.cend()); | |
correct = correct && (argv[i] == arg); | |
} | |
} | |
LocalFree(argvW); | |
std::cout << std::endl << ">> Correct: " << std::boolalpha << correct << std::endl; | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <string> | |
#include <vector> | |
#include <windows.h> | |
std::string ArgvToCommandLine(int argc, const char** argv) | |
{ | |
std::string result; | |
for (int i = 0; i < argc; ++i) { | |
std::string temp = argv[i]; | |
// Add slash (\) before double quotes (") and duplicate slashes before it | |
auto pos = temp.find('"'); | |
while (pos != std::string::npos) { | |
int cnt = 1; | |
while (pos > 0 && temp[pos-1] == '\\') { ++cnt, --pos; } | |
temp.insert(pos, cnt, '\\'); | |
pos = temp.find('"', pos + cnt * 2); | |
} | |
// Add quotes around string if whitespace chars are present (with slash duplicating at the end of string) | |
if (temp.find_first_of(" \t") != std::string::npos) { | |
pos = temp.size(); | |
int cnt = 0; | |
while (pos > 0 && temp[pos-1] == '\\') { ++cnt, --pos; } | |
if (cnt > 0) { temp.append(cnt, '\\'); } | |
temp = '"' + temp + '"'; | |
} | |
// Add space delimiter | |
if (i > 0) { result.push_back(' '); } | |
result.append(temp); | |
} | |
return result; | |
} | |
std::string ArgvToCommandLine(std::vector<const char*> str_vec) | |
{ | |
return ArgvToCommandLine(str_vec.size(), str_vec.data()); | |
} | |
std::wstring ArgvToCommandLineW(int argc, const wchar_t** argv) | |
{ | |
std::wstring result; | |
for (int i = 0; i < argc; ++i) { | |
std::wstring temp = argv[i]; | |
// Add slash (\) before double quotes (") and duplicate slashes before it | |
auto pos = temp.find(L'"'); | |
while (pos != std::wstring::npos) { | |
int cnt = 1; | |
while (pos > 0 && temp[pos-1] == L'\\') { ++cnt, --pos; } | |
temp.insert(pos, cnt, L'\\'); | |
pos = temp.find(L'"', pos + cnt * 2); | |
} | |
// Add quotes around string if whitespace chars are present (with slash duplicating at the end of string) | |
if (temp.find_first_of(L" \t") != std::wstring::npos) { | |
pos = temp.size(); | |
int cnt = 0; | |
while (pos > 0 && temp[pos-1] == L'\\') { ++cnt, --pos; } | |
if (cnt > 0) { temp.append(cnt, L'\\'); } | |
temp = L'"' + temp + L'"'; | |
} | |
// Add space delimiter | |
if (i > 0) { result.push_back(L' '); } | |
result.append(temp); | |
} | |
return result; | |
} | |
std::wstring ArgvToCommandLineW(std::vector<const wchar_t*> str_vec) | |
{ | |
return ArgvToCommandLineW(str_vec.size(), str_vec.data()); | |
} | |
int main(int argc, const char** argv) | |
{ | |
//* | |
const char* argv1[] = { | |
"test.exe", | |
"C:\\Program Files\\", | |
"normal\\", | |
"a\ttab", | |
"quote\"mark", | |
"\\\\\\\"", | |
" \" ", | |
"\"quote\\\"\"\ttab \\space\\\\\"" | |
}; | |
const int argc1 = sizeof(argv1)/sizeof(*argv1); | |
argv = argv1; | |
argc = argc1; | |
//*/ | |
std::cout << std::endl << ">> Source arguments:" << std::endl; | |
for (int i = 0; i < argc; ++i) { | |
std::cout << '[' << argv[i] << ']' << std::endl; | |
} | |
std::cout << std::endl << ">> ArgvToCommandLine:" << std::endl; | |
std::string cmdline = ArgvToCommandLine(argc, argv); | |
std::cout << '[' << cmdline << ']' << std::endl; | |
std::cout << std::endl << ">> CommandLineToArgvW:" << std::endl; | |
int argcW; | |
std::wstring cmdlineW(cmdline.cbegin(), cmdline.cend()); | |
wchar_t** argvW = CommandLineToArgvW(cmdlineW.c_str(), &argcW); | |
bool correct = (argc == argcW); | |
for (int i = 0; i < argcW; ++i) { | |
std::wcout << L'[' << argvW[i] << L']' << std::endl; | |
if (correct) { | |
std::wstring argW = argvW[i]; | |
std::string arg(argW.cbegin(), argW.cend()); | |
correct = correct && (argv[i] == arg); | |
} | |
} | |
LocalFree(argvW); | |
std::cout << std::endl << ">> Correct: " << std::boolalpha << correct << std::endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment