【发布时间】:2012-02-01 13:46:27
【问题描述】:
【问题讨论】:
【问题讨论】:
一个可能的解决方案:
#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查看在线演示。
【讨论】:
这样的事情会起作用
#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++ 方式:)
【讨论】:
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);
}
【讨论】:
char * seq_gen(char * prefix) {
static int counter;
char * result;
sprintf(result, "%s%03d", prefix, counter++);
return result;
}
这将使用 3 位填充字符串打印您的前缀。如果你想要一个长字符串,你所要做的就是尽可能多地提供前缀,并将上面代码中的 %03d 更改为你想要的任何长度的数字填充。
【讨论】:
嗯,这个想法很简单。只需存储当前数字并在每次生成新字符串时将其递增。您可以实现它来对迭代器进行建模以减少使用它的麻烦(然后您可以使用标准算法)。使用 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;
}
【讨论】:
看看标准库的字符串流。有一个您递增的整数,并在每次递增后插入到字符串流中。控制字符串长度,有填充字符的概念,还有width()成员函数。
【讨论】:
你有很多方法可以做到这一点。
一般来说,就像您展示的链接一样,有一组可能的字符。然后在每次迭代之后,从最右边的字符开始,递增它(即,将其更改为可能字符列表中的下一个字符),如果溢出,将其设置为第一个字符(索引 0)并转到第一个字符在左边。这就像在基数中增加一个数字,比如 62。
在您的具体示例中,您最好从另一个字符串和一个数字创建字符串。
如果你喜欢*printf,你可以用"IMG%04d"写一个字符串,并让参数从0变为任何值。
如果你喜欢stringstream,你也可以这样做。
【讨论】:
你所说的连续字符串到底是什么意思?
既然您提到您使用的是 C++ 字符串,请尝试使用 .string::append 方法。
string str, str2;
str.append("A");
str.append(str2);
查找 http://www.cplusplus.com/reference/string/string/append/ 以获取附加函数的更多重载调用。
【讨论】:
这是伪代码。你会明白我的意思:D
int counter = 0, retval;
do
{
char filename[MAX_PATH];
sprintf(filename, "IMG00%d", counter++);
if(retval = CreateFile(...))
//ok, return
}while(!retval);
【讨论】:
您必须保留一个计数器,每次获得新名称时都会增加。此计数器必须在您的应用程序结束时保存,并在您的应用程序启动时加载。
可能是这样的:
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();
【讨论】: