简体   繁体   中英

Convert from CString Array to Integer Array in MFC

I am stuck at this for 2 days since I am so new to C++.I want to use this function to convert from CString Array to Int Array but I dont know how it could be done. Is there any suggestions, Thanks in Advance !

Here are my code:

 void CCalculationBasicDlg::StringToIntegerArr(const CStringArray& arFields)
{
 int length = arFields.GetSize();
 int* arNum = new int[length];
 int tmp = 0; 
 for (int i = 0; i < length; i++)
 {
    tmp = _tstof(arFields[i]);
    arNum[i] = tmp;
 }
}

  // button to test function 
  void CCalculationBasicDlg::OnBnClickedBtnResult()
  { 
    UpdateData(TRUE);
    CString str_1, strDelimiters;
    CStringArray arFields1;

    edit_number_one.GetWindowText(str_1);
    m_ctrlDelimiters.GetWindowText(strDelimiters);

   // take String 1 and store in arFields1
   MyTokenizer(str_1, strDelimiters, arFields1);

   StringToIntegerArr(arFields1);
   // Can I put a breakpoint to test the integer array

   UpdateData(FALSE);
 }

The conversion is a simple matter of calling std::stoi (or std::atoi if you don't need error handling). The issue is complicated, because CString stores either ANSI (code page) or Unicode encoded characters.

Since std::stoi has overloads for both std::string and std::wstring , this is conveniently dealt with, by having the compiler construct the appropriate temporary from the CString 's controlled sequence:

std::stoi(cstr.GetString());  // invokes either string::string(const char*) or
                              //                wstring::wstring(const wchar_t*)

The conversion function can then be written as:

int* CCalculationBasicDlg::StringToIntegerArr(const CStringArray& arFields)
{
    int length = arFields.GetSize();
    int* arNum = new int[length];  // alternatively: std::vector<int> arNum(length);
    for (int i = 0; i < length; i++)
    {
        int value = std::stoi(arFields[i].GetString());
        arNum[i] = value;
    }
    return arNum;  // caller is responsible for clean-up
}


A few notes on the implementation:

  • Using a naked pointer ( int* arNum ) fails to address the requirements of exception safety. Both stoi as well as the (invisible) string / wstring constructors can throw exceptions, leaving the code with a memory leak. Use a smart pointer (eg std::unique_ptr ) instead.
  • Better yet, use a standard container to manage the storage entirely.
  • Use move semantics for better performance. When using a std::vector you don't have to do anything in particular. Simply return the local object, and the compiler will do the rest.
  • Since the code can throw C++ exceptions (just as your original code), make sure you understand the rules. In particular, all stack frames in between throwing and catching an exception must know about C++ exceptions. This is not in general true. As soon as you are called by the OS, all bets are off.

First of all, why do you use CStringArray and not a std::vector ? Do you know your array size over the hole Programm? When not please use vector. To create an array is a big task because you must allocate memory which creates a performance problem when it's used too often. The vector doesn't have these problems because of it's flexible size of alocated memory.

To convert a CString to Int you use std::atoi(CString). My Solution looks like this:

CStringArray test;
int help[100];
for (int i = 0; i < test.GetSize(); i++) {
    help[i] = std::atoi(test.ElementAt(i));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM