2017-08-03 73 views
3

我有一個C++函數,其接受字符串在以下格式加倍通過分隔符:允許用戶通過其在C++

<WORD>: [VALUE]; <ANOTHER WORD>: [VALUE]; ... 

這是函數:

std::wstring ExtractSubStringFromString(const std::wstring String, const std::wstring SubString) { 

    std::wstring S = std::wstring(String), SS = std::wstring(SubString), NS; 
    size_t ColonCount = NULL, SeparatorCount = NULL; WCHAR Separator = L';'; 

    ColonCount = std::count(S.begin(), S.end(), L':'); 
    SeparatorCount = std::count(S.begin(), S.end(), Separator); 

    if ((SS.find(Separator) != std::wstring::npos) || (SeparatorCount > ColonCount)) 
    { 
     // SEPARATOR NEED TO BE ESCAPED, BUT DON'T KNOW TO DO THIS. 
    } 

    if (S.find(SS) != std::wstring::npos) 
    { 
     NS = S.substr(S.find(SS) + SS.length() + 1); 

     if (NS.find(Separator) != std::wstring::npos) { NS = NS.substr(NULL, NS.find(Separator)); } 
     if (NS[NS.length() - 1] == L']') { NS.pop_back(); } 

     return NS; 
    } 
    return L""; 
} 

以上功能正確地輸出MANGO如果我使用它像:

ExtractSubStringFromString(L"[VALUE: MANGO; DATA: NOTHING]", L"VALUE") 

但是,如果我有兩個轉義分隔符在下面的字符串,我試着像;;翻番,但我仍然得到MANGO代替;MANGO;

ExtractSubStringFromString(L"[VALUE: ;;MANGO;;; DATA: NOTHING]", L"VALUE") 

在這裏,價值分配器是冒號和分隔符是分號。我希望允許用戶通過將額外的倍數加倍來將冒號和分號傳遞給我的函數。就像我們在很多腳本語言和編程語言中使用雙引號,單引號和許多其他語言一樣,也使用許多程序命令的參數。

我以爲很難,但甚至想不出一種辦法。任何人都可以在這種情況下幫助我嗎?

在此先感謝。

+1

*加倍額外的人* - 爲什麼不遵循這樣的事情,並在前面加上事實上的約定「\」如果它被認爲是一個文字字符而不是分隔符的話?加倍這樣的項目使得這項工作變得更加困難,海事組織 - 當你看到一個「\」時,你知道下一個字符被認爲是沒有特殊意義的文字字符。 – PaulMcKenzie

+1

我會建議查找json - 爲什麼要重新發明輪子? – UKMonkey

+0

@AlexG那麼如果string包含';;;'? – Blueeyes789

回答

2

您應該在字符串中搜索;;,並用臨時填充符charstring替換它,稍後可以引用它並將其替換爲該值。

所以基本上:

1)搜索通過串並與替換的;;所有實例\tempFill
- 這將是最好挑字符的組合,將是極不可能在原字符串。
2)解析字符串
3)替換爲的\tempFill所有實例;

注:這將是明智的,在您的字符串運行斷言,以確保您的\tempFill(或任何你選擇填充)不在原始字符串中以防止錯誤/錯誤/錯誤。您可以使用諸如\n之類的字符,並確保原始字符串中有非字符。

聲明: 我幾乎可以保證有更乾淨和更有效的方法來做到這一點,但這是最簡單的方法。

+0

@SergeBallesta我添加了一個註釋來運行斷言,但我會添加另一個警告。感謝您的高舉。當他們開始談話時,我刪除了我的評論:)。 –

2

首先作爲子串不需要被分割我假設它不需要預處理來過濾轉義分隔符。

然後在主字符串上,最簡單的方法是當您在字符串中搜索它們時,過濾掉轉義分隔符。僞代碼(假設封閉[]已被刪除):

last_index = begin_of_string 
index_of_current_substring = begin_of_string 
loop: search a separator starting at last index - if not found exit loop 
    ok: found one at ix 
    if char at ix+1 is a separator (meaning with have an escaped separator 
     remove character at ix from string by copying all characters after it one step to the left 
     last_index = ix+1 
     continue loop 
    else this is a true separator 
     search a column in [ index_of_current_substring, ix [ 
     if not found: error incorrect string 
     say found at c 
     compare key_string with string[index_of_current_substring, c [ 
     if equal - ok we found the key 
      value is string[ c+2 (skip a space after the colum), ix [ 
      return value - search is finished 
     else - it is not our key, just continue searching 
      index_of_current_substring = ix+1 
      last_index = index_of_current_substring 
      continue loop 

現在應該很容易將其轉換成C++