How to Copy the contents of a wxString into a char array

General questions regarding the usage of CodeLite
User avatar
ColleenKobe
CodeLite Expert
Posts: 130
Joined: Wed Mar 30, 2016 4:31 pm
Genuine User: Yes
IDE Question: C++
Contact:

How to Copy the contents of a wxString into a char array

Post by ColleenKobe »

I need to copy the contents of a wxString into a plain, ordinary, simple, character array [MAX_LENGTH] characters long.

I first thought to use:

Code: Select all

const wxCharBuffer wxString::mb_str ( const wxMBConv & conv = wxConvLibc ) const
because it seemed like a nice one-line copy from a wxString to a wxCharBuffer. But then, how to I copy the wxCharBuffer into the character array? Or even get a single character from a wxCharBuffer? I don't see any conversion methods on http://docs.wxwidgets.org/3.0/classwx_char_buffer.html. So that idea is out.

Then I thought to try converting one character at a time, using GetChar. Here is that code:

Code: Select all

#include "ut_bts.h"                     //  2i
#include "ut_gui.h"                     //  2j
#include "Settings_Class.h"             //  5r
class     Settings_Class;               //  5s
#include "Wrapper.h"                    //  5w
#include <wx/buffer.h>                  //  6
#include <wx/filename.h>                //  6
#include <wx/msgdlg.h>                  //  6
#include <wx/string.h>                  //  6
.
.
.
// +===========================================================================+
// |                       ut_gui_Set_Char_Array_to_wxSt                       |
// |                                                                           |
// |                          char array = wxString                            |
// |                                                                           |
// |  Description:  This procedure sets the incoming C-style character array   |
// |                to the contents of incoming wxString.                      |
// +===========================================================================+
void  ut_gui_Class::ut_gui_Set_Char_Array_to_wxSt
           (char        ch_array [gd_bts_FILENAME_LENGTH],
            wxString    wx_St)
{

    char    ch              = ' ';
    int     i               = 0;
    int     Max_Length      = 0;
    size_t  Length_of_wxSt  = 0;

    //  Initialize the target character array to end-of-string characters.
    memset  (&ch_array, '\0', gd_bts_FILENAME_LENGTH);

    Length_of_wxSt  = wx_St.Length  ();      // <-- GRRR!  Execution dies here.

    if (Length_of_wxSt == 0)                                    // Incoming wxString is
        ;                                                       // empty.  Just leave.

    else
    {
        if (Length_of_wxSt < (size_t) gd_bts_FILENAME_LENGTH)   // Set range limit.
            Max_Length  = Length_of_wxSt;
        else
            Max_Length  = gd_bts_FILENAME_LENGTH;

        for (i = 0; i < Max_Length; i++)                        // Aaaand...copy!
        {
            ch              = (char) wx_St.GetChar (i);
            ch_array [i]    = ch;
        }
    }
}   // ut_gui_Set_Char_Array_to_wxSt
The code compiles and links just fine. But when I stepped through execution, and I hit the line--
Length_of_wxSt = wx_St.Length ();
--execution crashes with a "Program Received signal SIGSEGV / Stack Trace is available in the 'Call Stack' Tab" error message. I didn't get any more details except for two links to lines in string.h that I don't understand.

At first I thought wx_St was empty. But no: I have a "Watch" on wx_St showing its value during ut_gui_Set_Char_Array_to_wxSt's execution. When ut_gui_Set_Char_Array_to_wxSt is called, wx_St's value is "F:\Temp\default.csv".

So I tried other things:

* changing wx_St's declaration in the argument list from
wxString wx_St
to
wxString * wx_St
and changed all the affected code appropriately. I still got SIGSEGV errors. I changed the code back, because I didn't want to risk modifying wx_St.

* creating a local wxString temp_wx_St, setting it to wx_St, and using temp_wx_St instead of wx_St. I got the same SIGSEGV error when execution hit the assignment to set temp_wx_St to wx_St.

* setting the local wxString temp_wx_St as follows:
temp_wx_St = wx_St.Capitalize ();
I got the SIGSEGV error.

The more things I tried, the more it seemed like NO MATTER HOW I access the incoming argument wx_St the first time--whether in a .GetChar or .Capitalize or .Clone--I get that SIGSEGV error.

SURELY COPYING A WXSTRING INTO A CHARACTER ARRAY IS NOT A NEW PROBLEM. It should be easier than this!!!

I do not have my heart set on following this approach. What do other people do copy a wxString into a C-type character array?

I am using:

Windows 10, 64 bits
CodeLite v12.0.2
MinGW

Thanks.
Colleen
DavidGH
CodeLite Plugin
Posts: 819
Joined: Wed Sep 03, 2008 7:26 pm
Contact:

Re: How to Copy the contents of a wxString into a char array

Post by DavidGH »

Hi,

I may be missing something, but I can't see what this has to do with the CodeLite IDE. It seems to me to be a pure wxWidgets issue; in which case I strongly suggest you ask on wxForum instead of here.

Regards,

David
User avatar
ColleenKobe
CodeLite Expert
Posts: 130
Joined: Wed Mar 30, 2016 4:31 pm
Genuine User: Yes
IDE Question: C++
Contact:

Re: How to Copy the contents of a wxString into a char array

Post by ColleenKobe »

Hi, DavidGH,

Thanks for asking.

I posted this message on the CodeLite forum because of my comments about how I stepped through the code, how I "watched" the values of the variables during execution, and how Codelite displayed two sections of the string.h file when the program crashed. Do other environments do those things, too?

I certainly can post the question elsewhere, but I've been "scolded" before about posting questions in the "wrong places," and I didn't want to experience that again. :-P

Colleen
DavidGH
CodeLite Plugin
Posts: 819
Joined: Wed Sep 03, 2008 7:26 pm
Contact:

Re: How to Copy the contents of a wxString into a char array

Post by DavidGH »

and how Codelite displayed two sections of the string.h file when the program crashed.
When a program being debugged segfaults, you should indeed see something relevant in the callstack. That's not just with CodeLite; CodeLite is 'just' a convenient way of displaying information from your debugger.
Do other environments do those things, too?
Yes.
I've been "scolded" before about posting questions in the "wrong places," and I didn't want to experience that again
I suggest you have a look at other peoples' posts and get a feel for their subjects. For example the last 3 non-Colleen posts in 'Using CodeLite' are: break points, how to disable code completion? and fastest way to open/build/run already exisiting C program. All 3 are clearly about CodeLite itself, not that user's code.
User avatar
ColleenKobe
CodeLite Expert
Posts: 130
Joined: Wed Mar 30, 2016 4:31 pm
Genuine User: Yes
IDE Question: C++
Contact:

Re: How to Copy the contents of a wxString into a char array

Post by ColleenKobe »

I solved the problem of the wx_St values not being accessible. The way I did that was to reverse the sequence the arguments were being sent into the procedure: now the wxString appears first, and THEN the char array. Also, neither argument is a pointer to a value; it's the actual value. The procedure now copies the wx_St into the ch_array just perfectly, and the ch_array is still correctly populated after the return from this procedure.

I cannot, however, explain why that fixed the problem. I've noted this quirk for future programs, but that's the extent of it.

I post this in case anyone else ever has a similar problem.

-- Colleen

Code: Select all

// +===========================================================================+
// |                       ut_gui_Set_Char_Array_to_wxSt                       |
// |                                                                           |
// |                          char array = wxString                            |
// |                                                                           |
// |  Description:  This procedure sets the incoming C-style character array   |
// |                to the contents of incoming wxString.                      |
// |                                                                           |
// |  Note:         Originally, I had the arguments wx_St and ch_array in the  |
// |                reverse sequence for this procedure, since that way, the   |
// |                sequence suggests "char array = wxString."  But for        |
// |                whatever reason, if the arguments are in that original     |
// |                sequence, wx_St becomes inaccessible and the program goes  |
// |                into lala land the first time it tries to access wx_St.    |
// |                Leave the arguments in this order.                         |
// +===========================================================================+
void  ut_gui_Class::ut_gui_Set_Char_Array_to_wxSt
           (wxString    wx_St,
            char        ch_array [gd_bts_FILENAME_LENGTH])
{

    int     i               = 0;
    int     Max_Length      = 0;
    size_t  Length_of_wxSt  = 0;

    //  Initialize the target character array to end-of-string characters.
    //  Don't set the first value of ch_array to null because later, you won't
    //  be able to copy characters there.
    memset  (&ch_array [1], '\0', gd_bts_FILENAME_LENGTH - 1);

    Length_of_wxSt  = wx_St.Length  ();

    if (Length_of_wxSt == 0)                                    // Incoming wxString is
        ;                                                       // empty.  Just leave.

    else
    {
        if (Length_of_wxSt < (size_t) (gd_bts_FILENAME_LENGTH - 1)) // Set range limit.
            Max_Length  = Length_of_wxSt;
        else
            Max_Length  = gd_bts_FILENAME_LENGTH - 1;

        for (i = 0; i < Max_Length; i++)                        // Aaaand...copy!
            ch_array [i]    = (char) wx_St.GetChar (i);
    }
}   // ut_gui_Set_Char_Array_to_wxSt
Post Reply