删除文件 C++ 中字符串中最后一个出现的字符

remove the last occurrence of character in string in file c++

本文关键字:字符 字符串 文件 C++ 删除 最后一个      更新时间:2023-10-16

我有一个函数,它读取文件中的每一行(使用 ifstream),修改该行,然后写入具有许多"{键,值}"的文件(通过使用 fstream),我需要删除该文件中的最后一个逗号,但搜索后,我仍然不知道这样做。

请问有人有什么建议吗?

当前输出文件:

//bein file
std::map <std::string, std::string> my_map = 
...
    {key,value},
    {key,value},
    {last_key,last_value},
};
//some comment

预期输出(删除最后一个逗号):

//bein file
std::map <std::string, std::string> my_map = 
...
    {key,value},
    {key,value},
    {last_key,last_value}
};
//some comment

我的代码在这里:

#include <windows.h>
#include <queue>
#include <string>
#include <iostream>
#include <regex> 
#include <fstream>
#include <iterator> 
#include <stdio.h>
// I think MS's names for some things are obnoxious.
const HANDLE HNULL = INVALID_HANDLE_VALUE;
const int A_DIR = FILE_ATTRIBUTE_DIRECTORY;

std::string write_cpp_file(std::string path, std::string line, std::string file_name)
{
    std::string result = "output\values.cpp";
    if  (path.find("values-en-rGB") != std::string::npos) {
        std::fstream file("./output/result.cpp", std::ios::out | std::ios::app);
        if  (file)
        {
            file << line << std::endl;
            file.close();
        }
    }
    return result;
}
void analyze_file(std::string const &path, WIN32_FIND_DATA const &file) { 
    //std::cout << "path: " << path << "n";
    //std::cout << "file name: " << file.cFileName << "n";
    std::string file_name = path+file.cFileName;
    std::cout << "processing file: " << file_name << "n";
    std::ifstream empSalariesOld(file_name);
    //ofstream empSalariesNew("EmpSalariesNew.txt");
    if (empSalariesOld)
    {
        std::string line;
        std::regex open_comment("(.*)(<!--)(.*)");
        std::regex close_comment("(.*)(-->)(.*)");
        std::regex string_tag("(.*)(<string name=)(.*)");
        std::regex find1("<string name=");
        std::string replace1 = "{";
        std::regex find2("">");
        std::string replace2 = "","";
        std::regex find3("</string>");
        std::string replace3 = ""},";
        std::string result;
        while (getline(empSalariesOld, line))
        {
            if (!std::regex_match(line, open_comment) && 
                !std::regex_match(line, close_comment) && 
                std::regex_match(line, string_tag) ) 
            {
                result = std::regex_replace(line, find1, replace1);
                result = std::regex_replace(result, find2, replace2);
                result = std::regex_replace(result, find3, replace3);
                std::string cpp_file = write_cpp_file(path, result, file_name);
            } 
        }
    }
    empSalariesOld.close();
    //empSalariesNew.close();
}
//process each file in folder/subfolder
void convert(std::string const &folder_name) {
    HANDLE finder;          // for FindFirstFile
    WIN32_FIND_DATA file;   // data about current file.
    std::priority_queue<std::string, std::vector<std::string>,
                       std::greater<std::string> > dirs;
    dirs.push(folder_name); // start with passed directory 
    do {
        std::string path = dirs.top();// retrieve directory to search
        dirs.pop();
        if (path[path.size()-1] != '')  // normalize the name.
            path += "\";
        std::string mask = path + "*";    // create mask for searching
        // traverse a directory. Search for sub-dirs separately, because we 
        // don't want a mask to apply to directory names. "*.cpp" should find
        // "ab.cpp", even though "a" doesn't match "*.cpp".
        //
        // First search for files:
        if (HNULL==(finder=FindFirstFile(mask.c_str(), &file))) 
            continue;
        do { 
            if (!(file.dwFileAttributes & A_DIR))
                analyze_file(path, file);
        } while (FindNextFile(finder, &file));
        FindClose(finder);
        // Then search for subdirectories:
        if (HNULL==(finder=FindFirstFile((path + "*").c_str(), &file)))
            continue;
        do { 
            if ((file.dwFileAttributes & A_DIR) && (file.cFileName[0] != '.'))
                dirs.push(path + file.cFileName);
        } while (FindNextFile(finder, &file));
        FindClose(finder);
    } while (!dirs.empty());
}
void create_output_folder()
{
    std::string command = "del /Q ";
    std::string path = "output\*.cpp";
    system(command.append(path).c_str());
    CreateDirectory("output", NULL);
}
int main() 
{
    create_output_folder();
    convert("./Strings");
    std::cout << "finish convert" << "n";
    return 0;
}

您可以执行以下操作,首次写入文件,而无需在循环外进行任何,。然后,对于其他人,在循环内写入,您可以在行首打印,

    if (getline(empSalariesOld, line))
    {
         if (!std::regex_match(line, open_comment) && 
            !std::regex_match(line, close_comment) && 
            std::regex_match(line, string_tag) ) 
        {
            result = std::regex_replace(line, find1, replace1);
            result = std::regex_replace(result, find2, replace2);
            result = std::regex_replace(result, find3, replace3);
            //remove the first char which is the comma
            result = result.substr(1, result.size()-1)
            std::string cpp_file = write_cpp_file(path, result, file_name);
        } 
    }
    while (getline(empSalariesOld, line))
    {
        if (!std::regex_match(line, open_comment) && 
            !std::regex_match(line, close_comment) && 
            std::regex_match(line, string_tag) ) 
        {
            result = std::regex_replace(line, find1, replace1);
            result = std::regex_replace(result, find2, replace2);
            result = std::regex_replace(result, find3, replace3);
            std::string cpp_file = write_cpp_file(path, result, file_name);
        } 
    }

我猜你把逗号放在replace3.您可以:

    std::string replace1 = ",n{"; \put the comma at beginning of line then got to the next line
    ...
    std::string replace3 = ""}"

由于您要将新行放入replace1因此应将其从新文件中删除:

 file << line;