windows文件路径和linux文件路径互转

        在使用Git Bash的时候经常碰到需要输入文件路径的情况,但是直接在windows下复制的文件路径bash无法正确的识别,会将\当成转义符处理,导致文件路径没有分隔符。每次都需要自己手动的修改。所以想着自己写个程序直接一键转换。

        首先需要获取剪贴板的内容,借助windows api函数来完成这个功能

static std::string getClipboard()
{
    if (OpenClipboard(NULL))
    {
        HANDLE hData = GetClipboardData(CF_TEXT);
        if (hData == nullptr)
        {
            return std::string();
        }
        char *pszText = static_cast<char *>(GlobalLock(hData));
        std::string text(pszText);
        GlobalUnlock(hData);
        CloseClipboard();
        return text;
    }
    else
    {
        std::cout << "Failed to open clipboard" << std::endl;
        return "";
    }
}

        获取剪贴板数据后,首先判断剪贴板中的内容是否是文件路径,以及返回文件路径是windows风格还是linux风格,这里借助正则表达式来完成

static int pathOrNot(const std::string &text)
{
    std::regex windowsPathRegex(R"(^[a-zA-Z]?:?[\.~]?(\\)([^\\:*?"<>|\r\n]+(\\)?)*$)");
    std::regex linuxPathRegex(R"(^[\.~]?/?(/[^/]+)+/?$)");
    if (std::regex_match(text, windowsPathRegex))
    {
        return 0;
    }
    else if (std::regex_match(text, linuxPathRegex))
    {
        return 1;
    }
    else
    {
        return -1;
    }
}

        然后是对文件路径的处理

static void toLinuxStyle()
{
    std::string text = getClipboard();
    if (text.empty())
    {
        return;
    }
    if ((pathOrNot(text) == 1) || (pathOrNot(text) == -1))
    {
        std::cout << "No need to operate" << std::endl;
        return;
    }
    replaceChar(text, '\\', '/');
    if (text[1] == ':')
    {
        deleteChar(text, 1);
        insertChar(text, '/', 0);
    }
    writeToClipboard(text);
    std::cout << text << std::endl;
}

static void towindowsStyle()
{
    std::string text = getClipboard();
    if (text.empty())
    {
        return;
    }
    if ((pathOrNot(text) == 0) || (pathOrNot(text) == -1))
    {
        std::cout << "No need to operate" << std::endl;
        return;
    }
    replaceChar(text, '/', '\\');
    if (text[0] == '\\')
    {
        deleteChar(text, 0);
        insertChar(text, ':', 1);
    }
    writeToClipboard(text);
    std::cout << text << std::endl;
}

        完整代码

#include <iostream>
#include <cstring>
#include <windows.h>
#include <regex>
#include <string>

#pragma comment(lib, "user32.lib")

static void toLinuxStyle();
static void towindowsStyle();
static void replaceChar(std::string &str, char target, char replacement);
static std::string getClipboard();
static int pathOrNot(const std::string &text);
static void deleteChar(std::string &str, int pos);
static void insertChar(std::string &str, char toInsert, int pos);
static void writeToClipboard(const std::string &text);

int main(int argc, char **argv)
{
    bool mode;
    if (argc < 2 || ((strcmp(argv[1], "-l") != 0) && (strcmp(argv[1], "-w") != 0)))
    {
        std::cout << "-w windows style\n-l linux style" << std::endl;
        mode = true;
    }
    else
    {
        if (strcmp(argv[1], "-l") == 0)
        {
            mode = true;
        }
        else
        {
            mode = false;
        }
    }
    if (mode)
    {
        toLinuxStyle();
    }
    else
    {
        towindowsStyle();
    }
    return 0;
}

static void toLinuxStyle()
{
    std::string text = getClipboard();
    if (text.empty())
    {
        return;
    }
    if ((pathOrNot(text) == 1) || (pathOrNot(text) == -1))
    {
        std::cout << "No need to operate" << std::endl;
        return;
    }
    replaceChar(text, '\\', '/');
    if (text[1] == ':')
    {
        deleteChar(text, 1);
        insertChar(text, '/', 0);
    }
    writeToClipboard(text);
    std::cout << text << std::endl;
}

static void towindowsStyle()
{
    std::string text = getClipboard();
    if (text.empty())
    {
        return;
    }
    if ((pathOrNot(text) == 0) || (pathOrNot(text) == -1))
    {
        std::cout << "No need to operate" << std::endl;
        return;
    }
    replaceChar(text, '/', '\\');
    if (text[0] == '\\')
    {
        deleteChar(text, 0);
        insertChar(text, ':', 1);
    }
    writeToClipboard(text);
    std::cout << text << std::endl;
}

static void replaceChar(std::string &str, char target, char replacement)
{
    for (char &c : str)
    {
        if (c == target)
        {
            c = replacement;
        }
    }
}

static std::string getClipboard()
{
    if (OpenClipboard(NULL))
    {
        HANDLE hData = GetClipboardData(CF_TEXT);
        if (hData == nullptr)
        {
            return std::string();
        }
        char *pszText = static_cast<char *>(GlobalLock(hData));
        std::string text(pszText);
        GlobalUnlock(hData);
        CloseClipboard();
        return text;
    }
    else
    {
        std::cout << "Failed to open clipboard" << std::endl;
        return "";
    }
}

static int pathOrNot(const std::string &text)
{
    std::regex windowsPathRegex(R"(^[a-zA-Z]?:?[\.~]?(\\)([^\\:*?"<>|\r\n]+(\\)?)*$)");
    std::regex linuxPathRegex(R"(^[\.~]?/?(/[^/]+)+/?$)");
    if (std::regex_match(text, windowsPathRegex))
    {
        return 0;
    }
    else if (std::regex_match(text, linuxPathRegex))
    {
        return 1;
    }
    else
    {
        return -1;
    }
}

static void deleteChar(std::string &str, int pos)
{
    if (pos < str.length())
    {
        str.erase(pos, 1);
    }
}

static void insertChar(std::string &str, char toInsert, int pos)
{
    if (pos <= str.length())
    {
        str.insert(pos, 1, toInsert);
    }
}

static void writeToClipboard(const std::string &text)
{
    if (OpenClipboard(nullptr))
    {
        EmptyClipboard();
        HGLOBAL hGlob = GlobalAlloc(GMEM_MOVEABLE, text.size() + 1);
        if (hGlob != nullptr)
        {
            LPVOID lpData = GlobalLock(hGlob);
            if (lpData != nullptr)
            {
                memcpy(lpData, text.c_str(), text.size() + 1);
                GlobalUnlock(hGlob);
                SetClipboardData(CF_TEXT, hGlob);
            }
        }
        CloseClipboard();
    }
}

        使用MSVC编译器编译

cl main.cpp -o pt 

然后把pt程序复制到git bash里的/usr/bin文件夹内,测试

猜你喜欢

转载自blog.csdn.net/qq_67328471/article/details/134828537