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

Posted

技术标签:

【中文标题】删除文件c ++中字符串中最后一次出现的字符【英文标题】:remove the last occurrence of character in string in file c++ 【发布时间】:2019-01-19 10:14:10 【问题描述】:

我有一个函数,它读取文件中的每一行(使用 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;

【问题讨论】:

通常的解决方案是仅在您是否处于最后一次迭代的情况下才输出冒号。提示:在迭代开始时输出冒号,如果是第一次迭代,则检查布尔变量。 如果您显示生成该输出的代码会更容易为您提供帮助。 模式 if(first) first = false; os &lt;&lt; ....; else os &lt;&lt; "," &lt;&lt; std::endl &lt;&lt; ....; 在我的经验中效果很好。 BitTickler:你说得对,我就是这样解决了我的问题 【参考方案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;

【讨论】:

以上是关于删除文件c ++中字符串中最后一次出现的字符的主要内容,如果未能解决你的问题,请参考以下文章

python去除出现一次的字符串

linux中 tr 命令的基础运用

删除行时文本文件中的特殊字符

sort,uniq,wc,history命令简介

删除字符串中的字符。输入一个字符串s,再输入一个字符c,将字符串s中出现的所有字符c删除。

把字符串的增删查改,插入以及删除各种操作封装为一个用c代码写的库,代码怎么写,我写不来求教