git,gitea - tool - creat Gitea Empty Rep Dir

文章目录

git,gitea - tool - creat Gitea Empty Rep Dir

概述

现在想采用小库的方式来使用gitea.

这样就涉及到开小库时,要用gitea命令行来做新的小库的目录。

以前做了实验,这样的脚本已经有了。

但是以这些脚本为模板,建立新的gitea库的目录时,需要改多个脚本中的绝对路径,很繁琐,容易错。

如果用git bash, 写一个脚本(e.g. sed), 来替换.bat中的绝对路径,控制的不细致。如果想控制的细致,对bash编程也没有那么熟悉。

那就用C来手搓一个工具,花了1天,挺好使的。

笔记

编译输出

就一个 creatGiteaEmptyRepDir.exe,拷贝到自己的gitea库的根目录

使用方式

bash 复制代码
creatGiteaEmptyRepDir.exe <新的小库名称 e.g. my_test>

因为操作的是gitea小库的初始目录,为了安全,如果库目录中已经有预期的文件夹,不会再操作,会提示并退出。没啥风险。

生成完的目录在./creatGiteaEmptyRepDir_out中的子目录中(e.g. ./creatGiteaEmptyRepDir_out/rep_my_test), 由用户(me)手工拷贝到gitea库的根目录,规避风险。

生成后的子库目录

使用说明

用写好的bat来建立gitea库的步骤

step1

关掉其他gitea控制台(因为端口都是3000)

运行 a1_run_gitea_rep_console.bat, 等待服务启动完成

step2

在浏览器中运行网页 http://localhost:3000/

选择sqlite3作为数据库, 将网页拉到底部,点击"立即安装"

等待安装完成,出现登录页面为止。

step3

建立库的用户

运行 a2_create_rep_user_pwd.bat 建立库用户

运行 b1_list_rep_user.bat 查看用户是否建立成功

step4

登录gitea库网页

在网页右上角的用户头像处点击下拉列表,选择设置 => SSH密钥 => 增加密钥,将生成在 C:\Users\me\.ssh 中的公钥id_rsa.pub内容增加未SSH密钥

创建仓库(只需要给出仓库名), 网页拉到尾部,点击"创建仓库"

step5

复制仓库地址, 好像本地ssh库地址不好使,只能复制http的库地址。

step6

迁出库地址。

首次迁出时,有警告,说库是空的,这是正常的,不用理会。

正常git提交。

other

如果要修改用户名和口令, 执行 b2_modify_rep_user_pwd.bat

如果要检查库的健康度, 执行 b3_run_gitea_doctor.bat

如果要查看gitea版本,执行 b4_show_git_env_info.bat

如果要打开一个cmd窗口, 执行 c1_call_cmd_here.bat

如果要手工执行git命令, 执行 c2_env_git.bat

工具源码

VS2019 c++ console

800行代码

c 复制代码
// @file creatGiteaEmptyRepDir.cpp
// 生成gitea用的库目录脚本, 用户自己拷贝生成的子目录(e.g. <./creatGiteaEmptyRepDir_out/sub_rep_dir>)到总的库目录(e.g. E:\my_git_rep), 防止意外操作或程序bug

#include <windows.h>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <fstream>

#include "resource.h"

#define MY_VER "1.0.0.0"
#define DIR_OUT "creatGiteaEmptyRepDir_out"

// 目录默认都要带尾巴上的\\

#define SET_GIT_GITEA_PATH "set PATH=C:\\Program Files\\Git\\bin;C:\\Program Files\\Git\\cmd;C:\\soft\\gitea;%PATH%"
#define MY_DEFAULT_GITEA_REP_ROOT_DIR "E:\\my_git_rep\\"
#define GIT_USER_NAME "name"
#define GIT_USER_PWD "password"
#define GIT_USER_EMAIL "me@x.com"

void usage();
void show_error(const char* psz_reason);
bool check_param(int argc, char** argv);
bool is_dir_exist(const char* psz_path_name);
std::string get_cur_dir_path_name();
bool create_dir(const char* pszPath);
std::string Wstring2String(std::wstring strW);
bool string_find(const std::string& strA, char c);

bool write_res_file(const char* psz_write_to);
bool write_ascii_file(const std::string& strFileName, const std::string& strText);

bool DoTask();
bool DoTask_a1_run_gitea_rep_console_bat();// a1_run_gitea_rep_console.bat
bool DoTask_a2_create_rep_user_pwd_bat();// a2_create_rep_user_pwd.bat
bool DoTask_b1_modify_rep_user_pwd_bat();// b1_list_rep_user.bat
bool DoTask_b2_modify_rep_user_pwd_bat();// b2_modify_rep_user_pwd.bat
bool DoTask_b3_run_gitea_doctor_bat();// b3_run_gitea_doctor.bat
bool DoTask_b4_show_git_env_info_bat();// b4_show_git_env_info.bat
bool DoTask_c1_call_cmd_here_bat();// c1_call_cmd_here.bat
bool DoTask_c2_env_git_bat();// c2_env_git.bat
bool DoTask_Readme_md(); // readme.md(在资源中, BIN_RES/IDR_BIN_RES_README_MD)

std::string g_new_sub_rep_name;
std::string g_cur_dir;
std::string g_dir_out; // 当前目录下的输出目录
std::string g_dir_out_obj; // 在当前输出目录中的目标目录, 需要用户手工拷贝到总库目录下 e.g. debug/out/rep_my_test
std::string g_dir_out_obj_rep; // 在当前输出目录中的目标目录中的库目录中的实际库目录 e.g. debug/out/rep_my_test/my_test
std::string g_dir_obj; // 要拷贝到的总目录下的子库目录
std::string g_dir_obj_rep; // 要拷贝到的总目录下的子库目录中的gitea库目录

int main(int argc, char** argv)
{
    do {
        if (!check_param(argc, argv))
        {
            usage();
            break;
        }

        if (!DoTask())
        {
            break;
        }

        printf("do task ok\r\n");
    } while (false);

    printf("\r\n");
    printf("END\r\n");
    system("pause");
    return 0;
}

bool DoTask()
{
    bool b_rc = false;

    do {
        if (!DoTask_a1_run_gitea_rep_console_bat())
        {
            break;
        }

        if (!DoTask_a2_create_rep_user_pwd_bat())
        {
            break;
        }

        if (!DoTask_b1_modify_rep_user_pwd_bat())
        {
            break;
        }

        if (!DoTask_b2_modify_rep_user_pwd_bat())
        {
            break;
        }

        if (!DoTask_b3_run_gitea_doctor_bat())
        {
            break;
        }

        if (!DoTask_b4_show_git_env_info_bat())
        {
            break;
        }

        if (!DoTask_c1_call_cmd_here_bat())
        {
            break;
        }

        if (!DoTask_c2_env_git_bat())
        {
            break;
        }

        if (!DoTask_Readme_md())
        {
            break;
        }

        b_rc = true;
    } while (false);

    return b_rc;
}

bool DoTask_a1_run_gitea_rep_console_bat()
{// a1_run_gitea_rep_console.bat
    bool b_rc = false;
    std::string strFileName;
    std::string strText;

    const char* pszShortFileName = "a1_run_gitea_rep_console.bat";

    do {
        strFileName = g_dir_out_obj;
        strFileName += pszShortFileName;

        std::stringstream ss;

        // @echo off
        ss << "@echo off\r\n";
        
        // rem a1_run_gitea_rep_console.bat
        ss << "rem " << pszShortFileName << "\r\n";

        // set PATH=C:\\Program Files\\Git\\bin;C:\\Program Files\\Git\\cmd;C:\\soft\\gitea;%PATH%
        ss << SET_GIT_GITEA_PATH << "\r\n";

        // call gitea --work - path E : \my_git_rep\rep_my_template\my_template
        ss << "call gitea --work-path ";
        ss << g_dir_obj_rep << "\r\n";

        strText = ss.str();
        if (!write_ascii_file(strFileName, strText))
        {
            break;
        }

        b_rc = true;
    } while (false);

    return b_rc;
}

bool DoTask_a2_create_rep_user_pwd_bat()
{// a2_create_rep_user_pwd.bat
    bool b_rc = false;
    std::string strFileName;
    std::string strText;

    const char* pszShortFileName = "a2_create_rep_user_pwd.bat";

    do {
        strFileName = g_dir_out_obj;
        strFileName += pszShortFileName;

        std::stringstream ss;

        // @echo off
        ss << "@echo off\r\n";

        //    rem a2_create_rep_user_pwd.bat
        ss << "rem " << pszShortFileName << "\r\n";

        //    set PATH = C:\Program Files\Git\bin; C:\Program Files\Git\cmd; C:\soft\gitea; % PATH%
        ss << SET_GIT_GITEA_PATH << "\r\n";
        
        //    call gitea --work - path E : \my_git_rep\rep_my_template\my_template
        ss << "call gitea --work-path ";
        ss << g_dir_obj_rep << " ";

        // admin user create --admin --username name --password pwd --email me@x.com --access-token
        ss << "admin user create --admin --username " << GIT_USER_NAME << " ";
        ss << "--password " << GIT_USER_PWD << " ";
        ss << "--email " << GIT_USER_EMAIL << " --access-token\r\n";

        //    PAUSE
        ss << "PAUSE" << "\r\n";

        strText = ss.str();
        if (!write_ascii_file(strFileName, strText))
        {
            break;
        }

        b_rc = true;
    } while (false);

    return b_rc;
}

bool DoTask_b1_modify_rep_user_pwd_bat()
{// b1_list_rep_user.bat
    bool b_rc = false;
    std::string strFileName;
    std::string strText;

    const char* pszShortFileName = "b1_list_rep_user.bat";

    do {
        strFileName = g_dir_out_obj;
        strFileName += pszShortFileName;

        std::stringstream ss;

        //@echo off
        ss << "@echo off" << "\r\n";

        //    rem b1_list_rep_user.bat
        ss << "rem b1_list_rep_user.bat" << "\r\n";

        //    set PATH = C:\Program Files\Git\bin; C:\Program Files\Git\cmd; C:\soft\gitea; % PATH%
        ss << SET_GIT_GITEA_PATH << "\r\n";

        //    call gitea --work - path E : \my_git_rep\rep_my_tools\my_tools admin user list
        ss << "call gitea --work-path " << g_dir_obj_rep << " admin user list" << "\r\n";

        //    PAUSE
        ss << "PAUSE" << "\r\n";

        strText = ss.str();
        if (!write_ascii_file(strFileName, strText))
        {
            break;
        }

        b_rc = true;
    } while (false);

    return b_rc;
}

bool DoTask_b2_modify_rep_user_pwd_bat()
{// b2_modify_rep_user_pwd.bat
    bool b_rc = false;
    std::string strFileName;
    std::string strText;

    const char* pszShortFileName = "b2_modify_rep_user_pwd.bat";

    do {
        strFileName = g_dir_out_obj;
        strFileName += pszShortFileName;

        std::stringstream ss;

        //@echo off
        ss << "@echo off" << "\r\n";

        //    rem b1_modify_rep_user_pwd.bat
        ss << "rem " << pszShortFileName << "\r\n";

        //    set PATH = C:\Program Files\Git\bin; C:\Program Files\Git\cmd; C:\soft\gitea; % PATH%
        ss << SET_GIT_GITEA_PATH << "\r\n";

        //    call gitea --work - path E : \my_git_rep\rep_my_template\my_template admin user change-password -u name -p pwd11111
        // 修改密码时, 密码的最小长度要为8
        ss << "call gitea --work-path " << g_dir_obj_rep << " ";
        ss << "admin user change-password -u " << GIT_USER_NAME << " ";
        ss << "-p " << " " << GIT_USER_PWD << "\r\n";

        //    PAUSE
        ss << "PAUSE" << "\r\n";

        strText = ss.str();
        if (!write_ascii_file(strFileName, strText))
        {
            break;
        }

        b_rc = true;
    } while (false);

    return b_rc;
}

bool DoTask_b3_run_gitea_doctor_bat()
{// b3_run_gitea_doctor.bat
    bool b_rc = false;
    std::string strFileName;
    std::string strText;

    const char* pszShortFileName = "b3_run_gitea_doctor.bat";

    do {
        strFileName = g_dir_out_obj;
        strFileName += pszShortFileName;

        std::stringstream ss;

        //@echo off
        ss << "@echo off" << "\r\n";

        //    rem b2_run_gitea_doctor.bat
        ss << "rem " << pszShortFileName << "\r\n";

        //    set PATH = C:\Program Files\Git\bin; C:\Program Files\Git\cmd; C:\soft\gitea; % PATH%
        ss << SET_GIT_GITEA_PATH << "\r\n";

        //    echo next, list gitea doctor runing
        ss << "echo next, list gitea doctor runing" << "\r\n";

        //    call gitea --work - path E : \my_git_rep\rep_my_template\my_template doctor check
        ss << "call gitea --work-path " << g_dir_obj_rep << " ";
        ss << "doctor check" << "\r\n";

        //    echo END
        ss << "echo END" << "\r\n";

        //    PAUSE
        ss << "PAUSE" << "\r\n";

        strText = ss.str();
        if (!write_ascii_file(strFileName, strText))
        {
            break;
        }

        b_rc = true;
    } while (false);

    return b_rc;
}

bool DoTask_b4_show_git_env_info_bat()
{// b4_show_git_env_info.bat
    bool b_rc = false;
    std::string strFileName;
    std::string strText;

    const char* pszShortFileName = "b4_show_git_env_info.bat";

    do {
        strFileName = g_dir_out_obj;
        strFileName += pszShortFileName;

        std::stringstream ss;

        //@echo off
        ss << "@echo off" << "\r\n";

        //    rem b4_show_git_env_info.bat
        ss << "rem " << pszShortFileName << "\r\n";

        //    set PATH = C:\Program Files\Git\bin; C:\Program Files\Git\cmd; C:\soft\gitea; % PATH%
        ss << SET_GIT_GITEA_PATH << "\r\n";

        //    gitea --version
        ss << "gitea --version" << "\r\n";

        //    PAUSE
        ss << "PAUSE" << "\r\n";

        strText = ss.str();
        if (!write_ascii_file(strFileName, strText))
        {
            break;
        }

        b_rc = true;
    } while (false);

    return b_rc;
}

bool DoTask_c1_call_cmd_here_bat()
{// c1_call_cmd_here.bat
    bool b_rc = false;
    std::string strFileName;
    std::string strText;

    const char* pszShortFileName = "c1_call_cmd_here.bat";

    do {
        strFileName = g_dir_out_obj;
        strFileName += pszShortFileName;

        std::stringstream ss;

        //@echo off
        ss << "@echo off" << "\r\n";

        //    rem c1_call_cmd_here.bat
        ss << "rem " << pszShortFileName << "\r\n";

        //    call cmd.exe
        ss << "call cmd.exe" << "\r\n";

        //    PAUSE
        ss << "PAUSE" << "\r\n";

        strText = ss.str();
        if (!write_ascii_file(strFileName, strText))
        {
            break;
        }

        b_rc = true;
    } while (false);

    return b_rc;
}

bool DoTask_c2_env_git_bat()
{// c2_env_git.bat
    bool b_rc = false;
    std::string strFileName;
    std::string strText;

    const char* pszShortFileName = "c2_env_git.bat";

    do {
        strFileName = g_dir_out_obj;
        strFileName += pszShortFileName;

        std::stringstream ss;

        //@echo off
        ss << "@echo off" << "\r\n";

        //    rem c2_env_git.bat
        ss << "rem " << pszShortFileName << "\r\n";

        //    set PATH = C:\Program Files\Git\bin; C:\Program Files\Git\cmd; C:\soft\gitea; % PATH%
        ss << SET_GIT_GITEA_PATH << "\r\n";

        //    call cmd.exe
        ss << "call cmd.exe" << "\r\n";

        strText = ss.str();
        if (!write_ascii_file(strFileName, strText))
        {
            break;
        }

        b_rc = true;
    } while (false);

    return b_rc;
}

bool DoTask_Readme_md()
{// readme.md(在资源中, BIN_RES/IDR_BIN_RES_README_MD)
    bool b_rc = false;
    std::string strFileName;
    std::string strText;

    const char* pszShortFileName = "readme.md";

    do {
        // 将嵌入资源中的readme.md写入输出文件夹中的库目录中
        strFileName = g_dir_out_obj;
        strFileName += pszShortFileName;
        if (!write_res_file(strFileName.c_str()))
        {
            break;
        }

        b_rc = true;
    } while (false);

    return b_rc;
}

bool write_res_file(const char* psz_write_to)
{
    // 定义资源标识符(根据实际资源头文件中的定义)
    const TCHAR* lpType = TEXT("BIN_RES");  // 自定义资源类型
    const int resId = IDR_BIN_RES_README_MD; // 资源ID

    if (NULL == psz_write_to) return false;

    // 获取模块句柄
    HMODULE hModule = GetModuleHandle(NULL);
    if (!hModule) return false;

    // 查找资源
    HRSRC hRes = FindResource(hModule, MAKEINTRESOURCE(resId), lpType);
    if (!hRes) return false;

    // 获取资源大小
    DWORD dwSize = SizeofResource(hModule, hRes);
    if (dwSize == 0) return false;

    // 加载资源
    HGLOBAL hGlobal = LoadResource(hModule, hRes);
    if (!hGlobal) return false;

    // 锁定资源获取指针
    LPVOID lpResData = LockResource(hGlobal);
    if (!lpResData) return false;

    // 创建输出文件
    HANDLE hFile = CreateFileA(psz_write_to, GENERIC_WRITE, 0, NULL,
        CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile == INVALID_HANDLE_VALUE) return false;

    // 写入文件
    DWORD dwWritten = 0;
    BOOL bResult = WriteFile(hFile, lpResData, dwSize, &dwWritten, NULL);

    // 清理资源
    CloseHandle(hFile);
    FreeResource(hGlobal);

    return (bResult && (dwWritten == dwSize));
}

bool check_param(int argc, char** argv)
{
    bool b_rc = false;
    std::string str_msg;
    char* psz = NULL;

    do {
        if (2 != argc)
        {
            break;
        }

        // g_new_sub_rep_name
        psz = argv[1];
        if ((NULL == psz) || (strlen(psz) <= 0))
        {
            std::stringstream ss;
            ss << "参数1是子库名称, 不能为空";
            str_msg = ss.str();
            show_error(str_msg.c_str());
            break;
        }

        g_new_sub_rep_name = psz;
        if (string_find(g_new_sub_rep_name, '/') || string_find(g_new_sub_rep_name, '\\'))
        {
            std::stringstream ss;
            ss << "新建的子库名称不能包含路径字符";
            str_msg = ss.str();
            show_error(str_msg.c_str());
            break;
        }

        g_cur_dir = get_cur_dir_path_name();
        if (!is_dir_exist(g_cur_dir.c_str()))
        {
            break;
        }

        // param1 = for_test
        g_dir_obj = MY_DEFAULT_GITEA_REP_ROOT_DIR;
        g_dir_obj += "rep_";
        g_dir_obj += g_new_sub_rep_name;
        g_dir_obj += "\\"; // E:\my_git_rep\rep_for_test\

        g_dir_obj_rep = g_dir_obj;
        g_dir_obj_rep += g_new_sub_rep_name;
        g_dir_obj_rep += "\\"; // E:\my_git_rep\rep_for_test\for_test\

        if (is_dir_exist(g_dir_obj.c_str()))
        {
            std::stringstream ss;
            ss << "总库下的子目录[" << g_dir_obj << "]已经存在, 为了安全, 请重新给定子库名称";
            str_msg = ss.str();
            show_error(str_msg.c_str());
            break;
        }

        g_dir_out = g_cur_dir;
        g_dir_out += DIR_OUT;
        g_dir_out += "\\";

        // 如果输出目录不存在,就建立目录
        if (!is_dir_exist(g_dir_out.c_str()))
        {
            // 建立输出目录
            if (!create_dir(g_dir_out.c_str()))
            {
                std::stringstream ss;
                ss << "目录[" << g_dir_out << "]建立失败";
                str_msg = ss.str();
                show_error(str_msg.c_str());
                break;
            }
        }

        // 建立输出目录中的子库目录
        g_dir_out_obj = g_dir_out;
        g_dir_out_obj += "rep_";
        g_dir_out_obj += g_new_sub_rep_name;
        g_dir_out_obj += "\\";

        if (!is_dir_exist(g_dir_out_obj.c_str()))
        {
            // 建立输出目录
            if (!create_dir(g_dir_out_obj.c_str()))
            {
                std::stringstream ss;
                ss << "目录[" << g_dir_out << "]建立失败";
                str_msg = ss.str();
                show_error(str_msg.c_str());
                break;
            }
        }
        else {
            // 如果目录存在,就不干活了, 必须用户移走了目录,才能干活
            std::stringstream ss;
            ss << "目录[" << g_dir_out_obj << "]已经存在,请移动目录到总库目录 或者 删除输出目录中的子库目录再运行程序";
            str_msg = ss.str();
            show_error(str_msg.c_str());
            break;
        }

        b_rc = true;
    } while (false);

    if (!b_rc)
    {
        show_error("命令行参数错误");
    }

    return b_rc;
}

std::string get_cur_dir_path_name() {
    // 使用MAX_PATH+1确保足够缓冲区
    char buffer[MAX_PATH + 1] = { 0 };

    // 获取EXE完整路径(ANSI版本)
    DWORD ret = GetModuleFileNameA(nullptr, buffer, MAX_PATH);
    if (ret == 0 || ret == MAX_PATH) { // 失败或路径过长
        return "";
    }

    // 反向查找最后一个路径分隔符
    char* last_sep = strrchr(buffer, '\\');
    if (last_sep == nullptr) { // 异常情况处理
        return "";
    }

    // 截断到目录部分(包含结尾反斜杠)
    *(last_sep + 1) = '\0';

    // 转换为标准字符串并返回
    return std::string(buffer);
}

bool is_dir_exist(const char* psz_path_name) {
    if (!psz_path_name) return false;

    const char* path = psz_path_name;
    struct _stat fileStat;

    if (_stat(path, &fileStat) == 0) {
        return (fileStat.st_mode & _S_IFDIR) != 0;
    }
    return false;
}

void show_error(const char* psz_reason)
{
    printf("error");

    if ((NULL != psz_reason) && (strlen(psz_reason) > 0))
    {
        printf(" : %s\r\n", psz_reason);
    }
    else {
        printf("\r\n");
    }

    printf("\r\n");
}

void usage()
{
    printf("-------- creatGiteaEmptyRepDir v%s --------\r\n", MY_VER);
    
    printf("usage :\r\n");
    printf("\t<THE_EXE> <gitea_rep_name>\r\n");
    printf("\tgitea_rep_name e.g. like my_gitea_study_rep\r\n");

    printf("function :\r\n");
    printf("\t生成gitea用的库目录脚本\r\n"); 
    printf("\t用户自己拷贝生成的子目录(e.g. <./creatGiteaEmptyRepDir_out/sub_rep_dir>)\r\n"); 
    printf("\t到总的库目录(e.g.E:/my_git_rep), 防止意外操作或程序bug\r\n");
}

bool create_dir(const char* pszPath) {
    if (!pszPath || *pszPath == '\0') {
        SetLastError(ERROR_INVALID_PARAMETER);
        return false;
    }

    // 转换UTF-8到宽字符(支持中文路径)
    const int bufferSize = MultiByteToWideChar(CP_UTF8, 0, pszPath, -1, nullptr, 0);
    if (bufferSize == 0) return false;

    std::wstring wPath(bufferSize, L'\0');
    if (MultiByteToWideChar(CP_UTF8, 0, pszPath, -1, &wPath[0], bufferSize) == 0) {
        return false;
    }

    // 检查路径有效性
    DWORD attrs = GetFileAttributesW(wPath.c_str());
    if (attrs != INVALID_FILE_ATTRIBUTES) {
        if (attrs & FILE_ATTRIBUTE_DIRECTORY) {
            SetLastError(ERROR_ALREADY_EXISTS);
            return false;
        }
        SetLastError(ERROR_FILE_EXISTS);
        return false;
    }

    // 创建目录(含基础权限)
    SECURITY_ATTRIBUTES sa = { sizeof(sa), nullptr, TRUE };
    if (CreateDirectoryW(wPath.c_str(), &sa)) {
        return true;
    }

    // 错误处理(可扩展记录日志)
    const DWORD err = GetLastError();
    if (err != ERROR_PATH_NOT_FOUND) {
        return false;
    }

    // 尝试创建父目录(可选递归)
    const std::wstring parentDir = wPath.substr(0, wPath.find_last_of(L'\\'));
    std::string parentDirA = Wstring2String(parentDir);
    if (!parentDir.empty() && create_dir(parentDirA.c_str())) {
        return CreateDirectoryW(wPath.c_str(), &sa) != 0;
    }

    return false;
}

std::string Wstring2String(std::wstring strW) {
    if (strW.empty())  return std::string();

    // 计算转换后需要的缓冲区大小
    int len = WideCharToMultiByte(
        CP_ACP,                // 使用系统默认 ANSI 编码(如中文系统下为 GBK)
        0,                     // 无特殊标志
        strW.c_str(),          // 输入宽字符串
        (int)strW.size(),       // 输入字符串长度(不含终止符)
        NULL, 0, NULL, NULL    // 输出缓冲区和长度置空以计算所需空间
    );

    if (len == 0) return std::string();

    // 直接操作 std::string 的缓冲区
    std::string result;
    result.resize(len);
    WideCharToMultiByte(
        CP_ACP, 0,
        strW.c_str(), (int)strW.size(),
        &result[0], len,       // 输出到 result 的缓冲区
        NULL, NULL
    );

    return result;
}

bool string_find(const std::string& strA, char c) {
    return strA.find(c) != std::string::npos;
}

bool write_ascii_file(const std::string& strFileName, const std::string& strText) {
    std::ofstream outFile;
    outFile.open(strFileName, std::ios::out | std::ios::trunc); // 覆盖模式写入

    if (!outFile.is_open()) { // 检查文件是否成功打开
        return false;
    }

    outFile << strText; // 写入内容
    outFile.close();     // 显式关闭文件

    return !outFile.fail();  // 返回写入是否成功
};

END

相关推荐
{⌐■_■}9 小时前
【git】提交修改、回撤、回滚、Tag 操作讲解,与reset (--soft、--mixed、--hard) 的区别
大数据·git·elasticsearch
GardenTu11 小时前
初尝git自结命令大全与需要理解的地方记录
git·github
真就死难19 小时前
Git是什么
git
机械心1 天前
代码管理git详细使用教程及最佳实践路径
git
hkj88081 天前
Git 常用命令
git
dawnkylin1 天前
通过 fork 为项目做出贡献
git·github
1379003402 天前
Git 设置代理
git
xiaodunmeng2 天前
sourcetree gitee 详细使用
git
前端郭德纲2 天前
vscode默认终端怎么设置成git bash
git·vscode·bash