2014-10-08 192 views
-1

我一直在研究一个开源项目,负责清理数据库的处理。在大多数地方,工作进展顺利,但在一个涉及自定义查询字符串操作的特定领域,代码一直很难看。C++和字符串连接分隔符

我们需要做的事情基本上是在运行时使用分隔符多次连接查询的特定组件。

它目前正在做的方法是设置一个计数器,遍历一组特定的检查值,如果我们有这个价值,我们追加“(%I,%I)”初始查询字符串,然后设置追加状态标志,然后我们追加“,(%i,%i)”这个工作,但是如果在循环中用一个标志构造一个标志,代码就会变得很奇怪,因为我们需要这个“,”分隔符最初的追加。

有一种类似于pythons的连接系统会更好,“join”构造。唯一的问题是字符串不在数组/矢量中,而是在运行时找到,并且要附加的字符串是常量。

有关如何处理此问题的任何建议?这种类型的附加的基于第一次出现的行为

https://github.com/addtheice/Server/blob/master/zone/tasks.cpp#L805-L867

一个例子。这实际上是这个可悲的更清洁的版本之一。

+0

示例代码请关于目前正在做什么。对不起,这只是帮助我思考。 – AndyG 2014-10-08 19:45:30

+1

“唯一的问题是字符串不在数组/矢量中,而是在运行时找到”。并存储在什么?如果你可以将它们放入可以迭代的_anything_(它不一定是内存集合;查看'istream_iterator'就可以得到一个简单的例子),那么你可以使用类似'boost :: algorithm :: join '在上面,或者很容易地编写你自己的等价物。 – abarnert 2014-10-08 19:51:32

+0

要追加的字符串是恒定的(或者是“(%i,%i)”或者“,(%i,%i)”,取决于它是否是第一个被添加的)。 如果要追加或不在运行时由数组内的某个值确定。 这就是为什么我不能只使用一些“,”。连接(迭代)结构像Python一样。我没有可迭代的集合,我有一个项目集合和一个常量字符串,我可能会或可能不会追加,第一个必须没有“,”之前和其他所有的字符串。 – 2014-10-08 19:54:35

回答

2

它可能不是最有效的方式,但我觉得我的代码在这种模式经常结束:

std::stringstream ss 
for(int i = 0; i < numberOfStrings; i++) 
    ss << (i ? "," : "") << GetString(i); 
std::string result = ss.str(); 
+0

这将工作,我们正试图避免我们目前有字符串流,所以我宁愿避免这种类型的构造,如果我可以。 这就是说,它绝对会工作。 这个构造的一些不那么简单的版本,例如,第一个应用实例可能在集合中间,而不是总是第一个元素,因为它可能不得不跳过大多数元素甚至所有元素,这会更困难! arghh – 2014-10-08 19:50:24

+0

好的,那么你可以创建一个'std :: string'的子类,它有一个新的方法'AppendElement(std :: string s)'。在内部,它保留了附加元素数量的计数器。它在计数器已经非零并且调用AppendElement时插入分隔符。 – jez 2014-10-08 19:54:23

+0

@AddtheIce *我们正在尝试避免stringstreams * - 出于何种原因? – Wolf 2017-09-21 12:17:41

0

怎么样从索引1而不是0的循环? 改编自您的代码:

char *buf = 0; 
MakeAnyLenString(&buf, "(%i, %i)", CharID, TasksEnabled[0]); 
TaskQuery += buf; 
safe_delete_array(buf); 
for(unsigned int i=1; i<TasksEnabled.size(); i++) { 
    MakeAnyLenString(&buf, ",(%i, %i)", CharID, TasksEnabled[i]); 
    TaskQuery += buf; 
    safe_delete_array(buf); 
} 
+0

这会在这种情况下工作,但这只是一个例子。我正在努力解决更大的问题。我们有构造,在我们应用或不应用元素之前,我们必须检查一些20个值符合特定的逻辑。 – 2014-10-08 20:00:53

+0

即,我正在寻找一种方法来追加一个带分隔符的连接常量字符串,*过滤*部分很容易做,应该是不被考虑的东西。 – 2014-10-08 20:01:54