Allow user to pass delimiter character by doubling it in C ++

I have a C ++ function that accepts strings in the following format:

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

      

This is the function:

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"";
}

      

The above function outputs correctly MANGO

if I use it like:

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

      

However, if I have two output delimiters on the next line, I tried to double as ;;

, but I still get MANGO

instead of ;MANGO;

:

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

      

Here the assignor of the values ​​is a colon and the separator is a semicolon. I want to allow users to pass colons and semicolons to my function, doubling extra. Just as we avoid double quotes, single quotes, and more in many scripting and programming languages, and in parameters in many program commands.

I thought hard, but couldn't even think how to do it. Can anyone help me with this situation?

Thanks in advance.

+3


source to share


2 answers


You have to search the string for ;;

and replace it with either a temporary placeholder char

or string

which can later be specified and replaced with a value.

So basically:

1) Search by string and replace all instances ;;

with \tempFill


- It is best to choose a combination of characters that are unlikely to be in the original string.
2) Parsing the string 3) Replace all instances \tempFill

with;




Note. It would be wise to run an assertion on your line to make sure yours \tempFill

(or whatever you choose to be filler) is not on the original line to prevent a bug / malfunction / error. You can use the type character \n

and make sure there isn't in the original string.

Disclaimer: I can almost guarantee there are cleaner, more efficient ways to do this, but this is the easiest way to do it.

+2


source


First, since the substring doesn't need to be delimited, I assume it doesn't need to pre-process the escaped delimiter filtering.

Then on the main string, the easiest way IMHO is to filter out the escaped delimiters when looking for them in the string. Pseudocode (assuming the attached one has []

been removed):



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

      

Now it is easy to convert it to C ++

+2


source







All Articles