【问题标题】:How to replace the value of a LPTSTR?如何替换 LPTSTR 的值?
【发布时间】:2021-12-11 09:37:37
【问题描述】:
    LPTSTR in;
    // ...

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

还有其他方法可以替换LPTSTR 的值吗?

在代码中,LPTSTRwchar_t*

【问题讨论】:

  • 您确定需要LPTSTR 吗?如果wstr 的范围足够大,你可以wstr.c_str()
  • 是的,我需要继续使用 LPTSTR,我只需要在确定的点更改她的值。
  • LPTSTR 不一定与std::wstring 兼容。如果要使用宽字符串,请显式使用宽字符串。如果有的话,如果你想坚持使用基于 Windows 的名称,那应该是 LPWSTR
  • LPTSTR 未在您的代码中分配。如果已分配,请使用wcscpy(in, wstr.c_str()); 进行复制。大概您正在将其传递给 API。根据使用情况,in = wstr.data(); 可能有效。
  • 是的,我需要继续使用 LPTSTR,我只需要在确定的点更改她的值即可。 -- 我敢打赌,情况并非如此.您可能认为您需要这样做。

标签: c++ windows


【解决方案1】:

当且仅当替换字符串小于/等于搜索字符串的长度时,您可以直接修改输入字符串的内容。

但是,如果替换字符串的长度大于搜索字符串,那么您将不得不分配一个更大的新字符串,并根据需要将您想要的字符复制到其中。

试试这样的:

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

明白为什么使用原始 C 风格的字符串指针比使用 C++ 风格的字符串类要困难得多吗?

【讨论】:

    【解决方案2】:

    LPTSTR 只是 wchar_t *。在这种情况下,您试图替换它指向的数据中的某些内容。

    为此,您需要确保它指向可修改的数据。在用文字初始化它的常见情况下,这是行不通的:

    LPCTSTR foo = "Foo";
    LPTSTR mFoo = (LPTSTR)"Foo";
    
    *foo = 'a'; // won't compile
    *mFoo = 'a'; // crash and burn
    

    为了使其可修改,您可以(对于一种可能性)将其初始化为指向正确类型数组的开头:

    wchar_t buffer[256] = L"Foo";
    
    LPTSTR foo = buffer;
    *foo = 'a';  // no problem
    

    修改字符串文字本身会失败,但这会分配一个数组,并从字符串文字初始化 it,然后修改该数组的内容。修改数组就好了。

    【讨论】:

    • LPTSTR foo = "Foo"; 不会编译。我想你的意思是 LPCTSTR 用超级奇怪的符号表示。
    • @BarmakShemirani:是的,我应该记得在处理这些东西时查一下。
    猜你喜欢
    • 2012-12-14
    • 1970-01-01
    • 1970-01-01
    • 2017-10-31
    • 2010-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    相关资源
    最近更新 更多