如何生成'连续'的c ++字符串?

时间:2012-01-03 14:20:00

标签: c++ string random

我想生成连续的C ++字符串,例如在摄像机中:IMG001,IMG002等能够指示前缀和字符串长度。

我找到了一个解决方案,我可以从具体字符集生成随机字符串:link

但我找不到想要达到的目标。

10 个答案:

答案 0 :(得分:8)

可能的解决方案:

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

std::string make_string(const std::string& a_prefix,
                        size_t a_suffix,
                        size_t a_max_length)
{
    std::ostringstream result;
    result << a_prefix <<
              std::setfill('0') <<
              std::setw(a_max_length - a_prefix.length()) <<
              a_suffix;
    return result.str();
}

int main()
{
    for (size_t i = 0; i < 100; i++)
    {
        std::cout << make_string("IMG", i, 6) << "\n";
    }
    return 0;
}

请参阅http://ideone.com/HZWmtI的在线演示。

答案 1 :(得分:2)

这样的事情会起作用

#include <string>
#include <iomanip>
#include <sstream>


std::string GetNextNumber( int &lastNum )
{
    std::stringstream ss;
    ss << "IMG";
    ss << std::setfill('0') << std::setw(3) << lastNum++;

    return ss.str();
}

int main()
{
    int x = 1;

    std::string s = GetNextNumber( x );
    s = GetNextNumber( x );


    return 0;
}

您可以使用int引用重复调用GetNextNumber以生成新的图像编号。您始终可以使用sprintf,但它不是c ++方式:)

答案 2 :(得分:1)

 const int max_size = 7 + 1; // maximum size of the name plus one 
 char buf[max_size];
 for (int i = 0 ; i < 1000; ++i) {
   sprintf(buf, "IMG%.04d", i);
   printf("The next name is %s\n", buf);
 }

答案 3 :(得分:1)

char * seq_gen(char * prefix) {
    static int counter;
    char * result;
    sprintf(result, "%s%03d", prefix, counter++);
    return result;
}

这将使用3位填充字符串打印您的前缀。如果你想要一个冗长的字符串,你所要做的就是尽可能多地提供前缀,并将上面代码中的%03d 更改为你想要的任何数字填充长度。

答案 4 :(得分:1)

嗯,这个想法很简单。只需存储当前数字,并在每次生成新字符串时将其递增。您可以实现它来模拟迭代器以减少使用它时的粗糙(然后您可以使用标准算法)。使用Boost.Iterator(它也应该适用于任何字符串类型):

#include <boost/iterator/iterator_facade.hpp>
#include <sstream>
#include <iomanip>

// can't come up with a better name
template <typename StringT, typename OrdT>
struct ordinal_id_generator : boost::iterator_facade<
    ordinal_id_generator<StringT, OrdT>, StringT,
    boost::forward_traversal_tag, StringT
> {
    ordinal_id_generator(
        const StringT& prefix = StringT(),
        typename StringT::size_type suffix_length = 5, OrdT initial = 0
    ) : prefix(prefix), suffix_length(suffix_length), ordinal(initial)
    {}
private:
    StringT prefix;
    typename StringT::size_type suffix_length;
    OrdT ordinal;

    friend class boost::iterator_core_access;

    void increment() {
        ++ordinal;
    }

    bool equal(const ordinal_id_generator& other) const {
        return (
               ordinal == other.ordinal
            && prefix == other.prefix
            && suffix_length == other.suffix_length
        );
    }

    StringT dereference() const {
        std::basic_ostringstream<typename StringT::value_type> ss;
        ss << prefix << std::setfill('0')
           << std::setw(suffix_length) << ordinal;
        return ss.str();
    }
};

示例代码:

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

typedef ordinal_id_generator<std::string, unsigned> generator;

int main() {
    std::ostream_iterator<std::string> out(std::cout, "\n");

    std::copy_n(generator("IMG"), 5, out);
    // can even behave as a range
    std::copy(generator("foo", 1, 2), generator("foo", 1, 4), out);

    return 0;
}

答案 5 :(得分:0)

看一下标准库的字符串流。有一个递增的整数,并在每次递增后插入到字符串流中。要控制字符串长度,有填充字符的概念和width()成员函数。

答案 6 :(得分:0)

你有很多方法可以做到这一点。

通用的那个,就像你展示的链接一样,有一个可能的字符数组。然后在每次迭代之后,从最右边的字符开始,将其递增(即,将其更改为可能的字符列表中的下一个字符),如果它溢出,则将其设置为第一个(索引0)并转到一个在左边。这就像在基数中增加一个数字,比如62。

在您的具体示例中,您最好从另一个字符串和数字创建字符串。

如果您喜欢*printf,可以使用"IMG%04d"编写一个字符串,并将参数从0变为任何值。

如果您喜欢stringstream,您也可以这样做。

答案 7 :(得分:0)

连续字符串究竟是什么意思?

由于您已经提到过您正在使用C ++字符串,请尝试使用.string::append方法。

string str, str2;
str.append("A");
str.append(str2);

查找http://www.cplusplus.com/reference/string/string/append/以查看追加函数的更多重载调用。

答案 8 :(得分:0)

每次获得新名称时,都必须保留一个增加的计数器。应用程序结束时必须保存此计数器,并在应用程序启动时加载。

可能是这样的:

class NameGenerator
{
public:
    NameGenerator()
        : m_counter(0)
        {
            // Code to load the counter from a file
        }

    ~NameGenerator()
        {
            // Code to save the counter to a file
        }

    std::string get_next_name()
        {
            // Combine your preferred prefix with your counter
            // Increase the counter
            // Return the string
        }

private:
    int m_counter;
}

NameGenerator my_name_generator;

然后像这样使用它:

std::string my_name = my_name_generator.get_next_name();

答案 9 :(得分:0)

它是伪代码。你会理解我的意思:D

int counter = 0, retval;
do
{
char filename[MAX_PATH];
sprintf(filename, "IMG00%d", counter++);
if(retval = CreateFile(...))
//ok, return
}while(!retval);