如何将带前导零的整数插入到std :: string中?

时间:2018-04-19 20:12:49

标签: c++ c++14 stdstring

在C ++ 14程序中,我得到一个像

这样的字符串
std::string  s = "MyFile####.mp4";

和0到几百的整数。 (它永远不会是一千个或更多,但以下是四位数。)我想用整数值替换“####”,根据需要使用前导零来匹配{{1}的数量}字符。什么是灵活的C ++ 11/14修改s或生成这样的新字符串的方法?

通常情况下,我会使用'#'个字符串和char*snprintf()来查找“strchr()”,但我想现在应该使用#更常见的是,但只知道它的最简单用途。

6 个答案:

答案 0 :(得分:6)

What is the slick C++11/14 way to modify s or produce a new string like that?

I don't know if it's slick enough but I propose the use of std::transform(), a lambda function and reverse iterators.

Something like

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

int main ()
 {
   std::string str { "MyFile####.mp4" };
   int         num { 742 };

   std::transform(str.rbegin(), str.rend(), str.rbegin(),
                    [&](auto ch) 
                     {
                       if ( '#' == ch )
                        {
                          ch   = "0123456789"[num % 10]; // or '0' + num % 10;
                          num /= 10;
                        }

                       return ch;
                     } // end of lambda function passed in as a parameter
                  ); // end of std::transform() 

   std::cout << str << std::endl;  // print MyFile0742.mp4
 }  

答案 1 :(得分:5)

我会使用正则表达式,因为你使用的是C ++ 14:

*

答案 2 :(得分:2)

当我玩它时,我失控了,嘿。

在命令行中传递模式,例如:

./cpp-string-fill file########.jpg '####' test###this### and#this

#include <string>
#include <iostream>
#include <sstream>

std::string fill_pattern(std::string p, int num) {
    size_t start_i, end_i;
    for(
        start_i = p.find_first_of('#'), end_i = start_i;
        end_i < p.length() && p[end_i] == '#';
        ++end_i
    ) {
        // Nothing special here.
    }

    if(end_i <= p.length()) {
        std::ostringstream os;
        os << num;
        const std::string &ns = os.str();
        size_t n_i = ns.length();
        while(end_i > start_i && n_i > 0) {
            end_i--;
            n_i--;
            p[end_i] = ns[n_i];
        }
        while(end_i > start_i) {
            end_i--;
            p[end_i] = '0';
        }
    }

    return p;
}

int main(int argc, char *argv[]) {
    if(argc<2) {
        exit(1);
    }
    for(int i = 1; i < argc; i++) {
        std::cout << fill_pattern(argv[i], 1283) << std::endl;
    }
    return 0;
}

答案 3 :(得分:2)

为什么不使用std::stringstream而不是将其转换为字符串。

std::string inputNumber (std::string s, int n) {
   std::stringstream sstream;
   bool numberIsSet = false;
   for (int i = 0; i < s; ++i) {
      if (s[i] == '#' && numberIsSet == true)
         continue;
      else if (s[i] == '#' && numberIsSet == false) {
         sstream << setfill('0') << setw(5) << n;
         numberIsSet = true;
      } else
         sstream << s[i];
   }

   return sstream.str();
}

答案 4 :(得分:1)

我可能会使用这样的东西

ARG KIBANA_VERSION=6.2.3
FROM docker.elastic.co/kibana/kibana:${KIBANA_VERSION}

USER root
RUN yum install -y which && yum clean all

USER kibana

ARG KIBANA_VERSION=${KIBANA_VERSION}

COPY kibana.yml /usr/share/kibana/config/kibana.yml
RUN ./bin/kibana-plugin install https://github.com/sivasamyk/logtrail/releases/download/v0.1.27/logtrail-${KIBANA_VERSION}-0.1.27.zip
COPY logtrail.json /usr/share/kibana/plugins/logtrail/logtrail.json

EXPOSE 5601

答案 5 :(得分:1)

我可能会这样做:

using namespace std;
#include <iostream>
#include <string>

int main()
{
    int SomeNumber = 42;
    string num = std::to_string(SomeNumber);
    string guide = "myfile####.mp3";
    int start = static_cast<int>(guide.find_first_of("#")); 
    int end = static_cast<int>(guide.find_last_of("#"));
    int used = 1;
    int place = end;
    char padding = '0';
    while(place >= start){
        if(used>num.length()){
            guide.begin()[place]=padding;
        }else{
            guide.begin()[place]=num[num.length()-used];
        }
        place--;
        used++;
    }
    cout << guide << endl; 

   return 0;
}