2014-10-08 211 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