Home > Net >  How to replace the value of a LPTSTR?
How to replace the value of a LPTSTR?

Time:10-26

    LPTSTR in;
    // ...

    std::wstring wstr(in);
    boost::replace_all(wstr, "in", ",");
    wcscpy(in, wstr.data());

There is any other way to replace the value of a LPTSTR?

In the code, LPTSTR is a wchar_t*

CodePudding user response:

An LPTSTR is just a wchar_t *. In this case, you're trying to replace something in the data it points at.

To do that, you need to assure it points at modifiable data. In the common case of initializing it with a literal, that won't work:

LPCTSTR foo = "Foo";
LPTSTR mFoo = (LPTSTR)"Foo";

*foo = 'a'; // won't compile
*mFoo = 'a'; // crash and burn

To make it modifiable, you can (for one possibility) initialize it to point at the beginning of an array of the correct type instead:

wchar_t buffer[256] = L"Foo";

LPTSTR foo = buffer;
*foo = 'a';  // no problem

Modifying the string literal itself will fail, but this allocates an array, and initializes it from the string literal, then modifies the content of that array. And modifying the array is fine.

CodePudding user response:

If, and only if, the replacement string is smaller/equal in length to the search string, then you can modify the contents of the input string directly.

However, if the replacement string is larger in length than the search string, then you will have to allocate a new string of larger size and copy the characters you want into it as needed.

Try something like this:

LPTSTR in = ...;

...

const int in_len = _tcslen(in);
LPTSTR in_end = in   in_len;

LPCTSTR search = ...; // _T("in")
const int search_len = _tcslen(search);

LPCTSTR replace = ...; // _T(",")
const int replace_len = _tcslen(replace);

LPTSTR p_in = _tcsstr(in, search);

if (replace_len < search_len)
{
    if (p_in != NULL)
    {
        const int diff = search_len - replace_len;

        do
        {
            memcpy(p_in, replace, replace_len * sizeof(TCHAR));
            p_in  = replace_len;
            LPTSTR remaining = p_in   diff;
            memmove(found, remaining, (in_end - remaining) * sizeof(TCHAR));
            in_end -= diff;
        }
        while ((p_in = _tcsstr(p_in, search)) != NULL);

        *in_end = _T('\0');
    }
}
else if (replace_len == search_len)
{
    while (p_in != NULL)
    {
        memcpy(p_in, replace, replace_len * sizeof(TCHAR));
        p_in = _tcsstr(p_in   replace_len, search);
    }
}
else
{
    int numFound = 0;
    while (p_in != NULL)
    {
          numFound;
        p_in = _tcsstr(p_in   search_len, search);
    }

    if (numFound > 0)
    {
        const out_len = in_len - (numFound * search_len)   (numFound * replace_len);
        LPTSTR out = new TCHAR[out_len   1];
        // or whatever the caller used to allocate 'in', since
        // the caller will need to free the new string later...

        LPTSTR p_out = out, found;

        p_in = in;
        while ((found = _tcsstr(p_in, search)) != NULL)
        {
            if (found != p_in)
            {
                int tmp_len = found - p_in;
                memcpy(p_out, p_in, tmp_len * sizeof(TCHAR));
                p_out  = tmp_len;
            }

            memcpy(p_out, replace, replace_len * sizeof(TCHAR));
            p_out  = replace_len;

            p_in = found   search_len;
        }

        if (p_in < in_end)
        {
            int tmp_len = in_end - p_in;
            memcpy(p_out, p_in, tmp_len * sizeof(TCHAR));
            p_out  = tmp_len;
        }

        *p_out = _T('\0');

        delete[] in;
        // or whatever the caller uses to free 'in'...

        in = out;
    }
}

See why working with raw C-style string pointers is so much harder than using C -style string classes?

  • Related