2016-09-09 47 views
1

我對此持續了2天,因爲我對C++這麼新。我想使用此函數從CString數組轉換爲Int數組,但我不知道它是如何可能的完成。有沒有任何建議,感謝提前!從CString數組轉換爲整數在MFC中的數組

這裏是我的代碼:

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); 
} 
+0

我認爲MFC容器已被STL容器所取代。我甚至懷疑微軟在他們生產的C++應用程序中再次使用MFC容器。因此,也許你應該學習STL,並放棄使用這些傳統的,過時的MFC,它們在15年前有目的,但現在不是。 – PaulMcKenzie

+0

你的問題到底是什麼?請描述它是什麼。 –

+1

順便說一句,使用STL它成爲1行程序,而不是15或20行:'std :: vector s; ... std :: vector v; ... std :: transform(s.begin(),秒。(),std :: back_inserter(v),std :: stoi);' – PaulMcKenzie

回答

3

轉換爲調用std::stoi(或std::atoi如果你不需要錯誤處理)的一個簡單的事情。問題很複雜,因爲CString存儲ANSI(代碼頁)或Unicode編碼的字符。

由於std::stoi具有用於既std::stringstd::wstring過載,這是方便的處理,通過具有編譯器構建適當的臨時從CString的控制的序列:

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

轉換函數可以寫成如:

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 
} 


上實施的幾個注意事項:

  • 使用裸指針(int* arNum)未能解決異常安全的要求。 stoi以及(看不見的)構造函數都會拋出異常,導致內存泄漏。改用智能指針(例如std::unique_ptr)。
  • 更好的是,使用標準容器來完全管理存儲。
  • 使用移動語義以獲得更好的性能。當使用std::vector時,您不必特別做任何事情。只需返回本地對象,編譯器將完成剩下的工作。
  • 由於代碼可能拋出C++異常(就像您的原始代碼一樣),請確保您瞭解規則。特別是,拋出和捕捉異常之間的所有堆棧幀都必須知道C++異常。這通常不是真的。一旦您被操作系統調用,所有投注都將關閉。
+0

謝謝你的幫助!轉換功能完美運作;我有3個編輯框,我推測我不知道輸入字符串,我可以調用這個函數,並從3個EditBoxes獲得3個不同的Interger數組? – NguyenHai

+0

再次感謝您的大力協助!我稱之爲函數: \t int length1 = arFields1.GetSize(); \t int * arNum1 = new int [length1]; \t arNum1 = StringToIntegerArr(arFields1); \t int length2 = arFields2.GetSize(); \t int * arNum2 = new int [length2]; \t arNum2 = StringToIntegerArr(arFields2); \t int result = arNum1 [3] + arNum2 [3]; 我的按鈕工作! – NguyenHai

+0

@NguyenHai:這會產生內存泄漏。你正在分配數組兩次。它實際上也很容易:'int * arNum1 = StringToIntegerArr(arrFields1);'當你通過調用'delete [] arNum1;''來完成'arNum1'時,你還必須正確清理'arNum1'。由於您是C++的新手,請查看[The Definitive C++ Book Guide and List](http://stackoverflow.com/q/388242/1889329)。 – IInspectable

1

首先,爲什麼要使用的CStringArray,而不是一個std :: vector的? 你知道你的數組大小超過程序嗎?請不要使用矢量。創建數組是一項艱鉅的任務,因爲您必須分配內存,這會在使用太頻繁時造成性能問題。矢量沒有這些問題,因爲它具有靈活的分配內存大小。

若要將CString轉換爲Int,請使用std :: atoi(CString)。我的解決辦法是這樣的:

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

*「創建陣列是一項艱鉅的任務,因爲您必須分配內存」* - 嗯,是的。如果你需要分配內存,你需要分配內存。幾乎不是「大任務」*。 *「矢量沒有這些問題,因爲它具有靈活的分配內存大小。」* - 矢量與**手動管理的動態數組完全相同。你只是沒有看到所有這些對'operator new []'的調用。您提供的代碼展示UB的字符串數組大小超過100.並且您建議使用沒有適當錯誤報告的函數('atoi')。 – IInspectable

+0

是的「大任務」是一個不好的表達。是的,我知道該向量也分配內存,但是當您經常更改數組大小時,向量會更有效,因爲向量會保留額外的內存,向量不會爲每個push_back分配內存。 –

+0

另外,如果你定義了'UNICODE'(你應該),'std :: atoi'的調用將不會被編譯。 – IInspectable