-3
case IDC_ADD:
    {
        //1. получаем данные из поля IDC_EDIT_ADD:
        char buf[MAX];
        memset(buf, 0, MAX);
        GetDlgItemTextA(hwnd, IDC_EDIT_ADD, buf, MAX);
        if (CheckData(buf)) {
            //2. Добавляем в БД buf:
            obj.AddData(buf);
            string s = regex_replace(buf, regex(" 
(\\w+);.\\d+"), string("$1"));
            //3. добавляем строку в список:
            SendDlgItemMessage(hwnd, IDC_LIST, LB_ADDSTRING, 0, 
(LPARAM)s.c_str());
            //4. очищаем само поле:
            SetDlgItemText(hwnd, IDC_EDIT_ADD, L"");
        }
        else
            MessageBox(NULL, L"Данные должны быть ввида 
[Футболист;ЗП]", L"Неверный формат ввода", MB_OK | 
MB_ICONINFORMATION);
        return TRUE;
    }

I want to save text in txt file. I enter "something" in edit control and click IDC_ADD, then I debug code and char array buf has \0 after each element. I think it is cause why "something" is not saved.

Vadim
  • 27
  • 5
  • 4
    You may want to read this: [Why not upload images of code/data/errors when asking a question?](https://meta.stackoverflow.com/q/285551/12149471) – Andreas Wenzel Mar 10 '23 at 05:26
  • Pro-tip. You can declare `char buf[MAX] = {0};` instead of having to explicitly memset it to all zeros. – selbie Mar 10 '23 at 05:28
  • or even [`char buf[MAX] = {};`](https://stackoverflow.com/questions/5591492/array-initialization-with-0-0) – yano Mar 10 '23 at 05:29
  • 2
    Also, please stop explicitly casting things to TCHAR and LPTSTR. Use wchar_t or char explicitly as you need them. TCHAR is a relic of Windows 98. – selbie Mar 10 '23 at 05:30

1 Answers1

4

What you are seeing is called Unicode. Or more specifically: UTF-16. Aka "wide strings". Which is every character is 16 bits (2 bytes) instead of 8 bits.

By default, most Visual C++ programs compile with UNICODE enabled by default. Just stick with Unicode 16-bit strings and use wchar_t* and std::wstring inplace of char* and std::string when interacting with the Windows API.

There's even a wregex library for wide string as well.

The bug in your code is that you are explicitly casting buf to LPTSTR. You probably did that because that's what enabled it to compile.

Better:

wchar_t buf[MAX] = {};
GetDlgItem(hwnd, IDC_EDIT_FLD, buf, MAX);

If you need to convert between ascii and wide strings, Windows offers the APIs: MultiByteToWideChar and WideCharToMultiByte.

Of if you want to call a Windows API with an ascii string, you can explicitly use the "A" variety:

char buf[MAX] = {};
GetDlgItemA(hwnd, IDC_EDIT_FLD, buf, MAX);

Or "W" variety, which is the default anyway:

wchar_t buf[MAX] = {};
GetDlgItemW(hwnd, IDC_EDIT_FLD, buf, MAX);

As I called out in the comment above, LPTSTR and related TCHAR types are an ancient relic of Windows programming that needs to be wiped from the face of the earth. It's what enabled Windows 9x programs to be compiled with ASCII API support and Windows NT programs to be compiled as Unicode. Unless you have a requirement to back port your code to Windows 98, you don't need to dink with TCHAR types.

selbie
  • 100,020
  • 15
  • 103
  • 173