简体   繁体   English

将字符串从字符串向量放入主字符串

[英]placing strings from a string vector into main string

I want to place strings from a string vector to a string.我想将字符串从字符串向量放入字符串。 here's the code I have tried:这是我尝试过的代码:

#include <iostream>
#include <cstdio>
#include <vector>
#include <string>

using namespace std;

int main()
{
    const char* event = "this is %s, %s and %s";
    std::vector<string> strs = {"sam", "joey", "chandler"};
    char buffer[200];

    std::vector<string>::iterator it;

    for(it = strs.begin(); it < strs.end(); it++)
    {
        sprintf(buffer, event, it->c_str());
    }

    std::cout << buffer;
    return 0;
}

the result i expected is it will replace %s flags in event strings with strings inside strs vector.我预期的结果是它将用 strs 向量中的字符串替换事件字符串中的 %s 标志。 however i got Segmentation fault (core dumped) error.但是我遇到了Segmentation fault (core dumped)错误。

can you please point out my mistake.你能指出我的错误吗?

EDIT编辑

the length of the vector is variable.向量的长度是可变的。 I have a template of strings with variable number of %s flags and I am trying to write a function where we can pass a vector and replace those flags with strings in vector.我有一个带有可变数量%s标志的字符串模板,我正在尝试编写一个函数,我们可以在其中传递一个向量并用向量中的字符串替换这些标志。

example of these strings are: "hello %s, meet %s" "welcome %s" "today is %s, and we want %s to work with you"这些字符串的例子是:“你好 %s,认识 %s”“欢迎 %s”“今天是 %s,我们希望 %s 和你一起工作”

Your mistake is that printf is plain inappropriate for what you want to do.你的错误是printf显然不适合你想做的事情。 I suggest simple substring "%s" search and replace.我建议简单的子字符串"%s"搜索和替换。 It's easy enough and surely safer.这很容易,而且肯定更安全。

std::string formatter(const char* event, const std::vector<string> &strs) {
    std::string buffer(event);

    size_t off = 0;
    for (auto placeholder : strs) {
        size_t i = buffer.find("%s", off);
        if (i == std::string::npos)
            break;

        buffer.erase(i, 2);
        buffer.insert(i, placeholder);
        off = i;
    }

    return buffer;
}

int main() {
    std::cout << formatter("this is %s, %s and %s", { { "sam", "joey", "chandler" } }) << "\n";
    std::cout << formatter("welcome %s", { { "sam", "joey", "chandler" } }) << "\n";
    std::cout << formatter("today is %s, and we want %s to work with you", { { "sam", "joey", "chandler" } }) << "\n";
}

Produces生产

this is sam, joey and chandler
welcome sam
today is sam, and we want joey to work with you

aCraig5075 has the right approach I think. aCraig5075 有我认为正确的方法。 Here's something similar that utilizes the vector:这是利用向量的类似内容:

int main()
{
    std::string event {"this is %s, %s and %s"};
    std::string flag = "%s";
    std::vector<std::string> strs = {"sam", "joey", "chandler", "fred"};
    std::vector<std::string>::iterator it = strs.begin();
    std::size_t found = event.find(flag);
    while (it != strs.end() && found != std::string::npos) {  //terminates at shortest
        event.replace(found, flag.length(), *it);
        found = event.find(flag);
        ++it;
    }
    std::cout << event << std::endl;
}

This will play nicely if there is a mismatch between the number of flags in the string and the number of strings in the vector, halting the loop if either is exhausted.如果字符串中的标志数量与向量中的字符串数量不匹配,这将很好地发挥作用,如果其中一个耗尽,则停止循环。

You're trying to make three separate calls to sprintf , but in each call you're passing it three %s conversions, so the first time it tries to print out three strings, even though you've only passed one.您试图对sprintf进行三个单独的调用,但在每次调用中,您都向它传递了三个%s转换,因此它第一次尝试打印出三个字符串,即使您只传递了一个。 If it finished executing the first iteration, on the second iterations you'd do the same thing again: pass one string, but tell it to expect three.如果它完成了第一次迭代,在第二次迭代中你会再次做同样的事情:传递一个字符串,但告诉它期待三个。 Same again the third time.第三次也一样。

It's not at all clear to me why you'd do any of this though.我完全不清楚你为什么要这样做。 You can produce the output you seem to want with code on this order:您可以使用以下顺序的代码生成您想要的输出:

std::vector<string> strs = {"sam", "joey", "chandler"};
std::cout << "This is: " << strs[0] << ", " << strs[1] << " and " << strs[2];

You can have a look at the usage of sprintf , and if you want to continue to use your code format, my approach is:你可以看看sprintf用法,如果你想继续使用你的代码格式,我的做法是:

#include <iostream>
#include <cstdio>
#include <vector>
#include <string>

using namespace std;

int main()
{

    const char* event = "this is %s, %s and %s";
    std::vector<string> strs = {"sam", "joey", "chandler"};
    char buffer[200];

    sprintf(buffer, event, strs[0].c_str(),strs[1].c_str(),strs[2].c_str());

    std::cout << buffer<<endl;
    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM