C++ 用 <algorithm> 屏蔽字符串的所有字符,除了最后 n 个字符

Posted

技术标签:

【中文标题】C++ 用 <algorithm> 屏蔽字符串的所有字符,除了最后 n 个字符【英文标题】:C++ masking all characters of a string except for the last n characters with <algorithm> 【发布时间】:2021-08-27 07:15:25 【问题描述】:

C++中,如何使用&lt;algorithm&gt;屏蔽字符串中除最后一个字符之外的所有字符?

即; 我有一个字符串

std::string barcode = "300001629197835714";

我想得到输出

**************5714

这个程序可以用传统的方式轻松完成,

    std::string barcode = "300001629197835714";
    std::string out;
    for (int i=0;i<barcode.length();i++)
    
        if (i<barcode.length()-4)
        
            out+="*";
        
        else
        
            out+=barcode[i];
        
    
    std::cout<<out;

但是我可以使用std::replace_ifstd::transform&lt;algorithm&gt; 标头中的任何函数吗?

【问题讨论】:

【参考方案1】:

这是一个使用算法库和迭代器的解决方案。我使用std::prevend() 之前获取4 个字符的迭代器,然后使用std::fill[begin, end - 4) 范围内的数字替换为'*'

#include <algorithm>
#include <string>
#include <iterator>
#include <iostream>

int main()

    std::string barcode = "300001629197835714";
    std::fill(barcode.begin(), std::prev(std::end(barcode), 4), '*');
    std::cout << barcode;

注意

std::prev(std::end(barcode), 4)

如果 barcode 少于 4 个字符,将导致未定义的行为。

【讨论】:

std::fill 会是最快的,太棒了!【参考方案2】:

std::replace_ifstd::transform 都不是必需的。简单的

barcode.replace(0, barcode.size() - 4, barcode.size() - 4, '*');
std::cout << barcode;

确保barcode.size() 大于 4。

std::basic_string::replace (6).

【讨论】:

【参考方案3】:

对于字符串操作,我通常会使用正则表达式而不是算法

#include <iostream>
#include <regex>
#include <string>

int main()

    std::string barcode = "300001629197835714";
    std::regex expression ".(?=.4,$)" ;
    auto secret = std::regex_replace(barcode, expression, "*");
    std::cout << secret << std::endl;

【讨论】:

正则表达式在这里是多余的。 没有。没有矫枉过正。惯用的正确解决方案。顺便说一下。唯一正确的解决方案,因为所有其他答案都会破坏原始字符串。 . . @ArminMontigny 复制原始字符串比使用正则表达式便宜得多。 矫枉过正视情况而定。对于arduino?是的,我不会使用它,它确实是矫枉过正。如果说它必须在 pc 上运行并且它将在我必须维护多年的产品中......是的,我会使用它,原因是:仅在真正需要时优化速度/内存,否则优化可维护性。因此源代码必须易于阅读(以便其他人也可以理解它(或找到公开可用的信息,如正则表达式)并尽可能多地重用现有和经过测试的 (!!!) 代码,就像标准库一样。【参考方案4】:

您可以将replace_if 与始终返回true 的谓词一起使用,并且只需使用从begin()end()-4 的迭代器:

#include <string>
#include <algorithm>
#include <iostream>
int main()
 

    std::string code = "1234564598745774";
    int numVisibleDigits = 4;
    std::replace_if(
        code.begin(),
        code.end()-numVisibleDigits,
        [](char)return true;,
        '*'
        );
    std::cout << code << std::endl;
 

【讨论】:

【参考方案5】:

可以通过std::replace_if完成

    std::string barcode = "300001629197835714";
    int nonMasklenght = 4;
    std::replace_if(barcode.begin(), barcode.end(), [&barcode, &nonMasklenght](const char &x)->bool 
                    size_t index = &x - &barcode[0];
                    return (index <( barcode.length() - nonMasklenght) );,
                    '*');
    std::cout<<barcode;

ideone example

【讨论】:

barcode = std::string(barcode.length() - nonMasklenght, '*') + barcode.substr(barcode.length() - nonMasklenght);【参考方案6】:

如果我查看OP的原始代码,那么我们可以清楚地看到原始字符串不应该被修改。

应该只显示被屏蔽的输出。

因此,除了 Pepijn Kramer 之外,几乎所有答案都是错误的。

顺便说一句。修改不是必需的,也不是必需的。简单地显示被屏蔽的输出:

#include <iostream>
#include <string>

int main() 

    // Our base data. It is const. It will not be modified
    const std::string barcode = "300001629197835714";

    // No algorithm and code
    // - - -

    // Just output
    std::cout << std::string(14, '*') << barcode.substr(barcode.length() - 4) << '\n';

    return 0;

【讨论】:

以上是关于C++ 用 <algorithm> 屏蔽字符串的所有字符,除了最后 n 个字符的主要内容,如果未能解决你的问题,请参考以下文章

C++ string 分割成 vector 分隔符

C++ string 分割成 vector 分隔符

C++ <algorithm> sort() 使用对象作为比较定义

c++用sort对vector排序问题

c++用sort对vector排序问题

C++ 关于unique的用法