删除文件c ++中字符串中最后一次出现的字符

时间:2019-01-19 10:14:10

标签: c++ string file fstream

我有一个函数(使用ifstream)读取文件中的每一行,修改该行,然后将其写入具有许多“ {key,value},”的文件(通过使用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
        // "a\b.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;
}

1 个答案:

答案 0 :(得分:1)

您可以执行以下操作以首先写入文件,而不会在循环外出现任何,。然后,对于其他人,请在循环内编写代码,然后在行的开头打印,

    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;