- ベストアンサー
CStingをTCHAR[]に変換したい - VC++でファイルリスト一覧作成ソフトを作成
- CSting型の_T("~\0~\0\0")をTCHAR[]に変換したいです。
- 現在は、4096文字の文字列配列にCSting型の変数DeleteFilePathを入れています。
- ファイルのパスをゴミ箱に削除するために、SHFileOperation関数を使用しています。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
// resultを動的に確保してない点が気になりますが では std::basic_string で。 #define _UNICODE #define UNICODE #define _AFXDLL #include <afx.h> #include <tchar.h> #include <string> #include <iostream> typedef std::basic_string<TCHAR> tstring; int main() { const wchar_t nc = L'\0'; CString input = L""; input += L"abc"; input += nc; input += L"def"; input += nc; input += L"ghi"; input += nc; input += nc; tstring buffer(static_cast<const _TCHAR*>(input), input.GetLength()); const _TCHAR* result = buffer.data(); for ( int i = 0; i < buffer.size(); ++i ) { if ( result[i] == L'\0' ) std::wcout << "'\\0'" << std::endl; else std::wcout << result[i] << std::endl; } }
その他の回答 (3)
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
_tcscpyはナル文字を見つけた時点でコピーをやめちゃいますよ。 /* * std::copyを使った例 * cl -EHsc -MD trial.cpp */ #define _UNICODE #define UNICODE #define _AFXDLL #include <afx.h> #include <tchar.h> #include <iostream> #include <algorithm> // 必須! int main() { const wchar_t nc = L'\0'; CString input = L""; input += L"abc"; input += nc; input += L"def"; input += nc; input += L"ghi"; input += nc; input += nc; _TCHAR result[16]; const _TCHAR* p = static_cast<const _TCHAR*>(input); // inputの先頭から長さ分をresultにコピー std::copy(p, p+input.GetLength(), result); for ( int i = 0; i < 16; ++i ) { if ( result[i] == L'\0' ) std::wcout << "'\\0'" << std::endl; else std::wcout << result[i] << std::endl; } }
補足
できました!ありがとうございます! 一応、ソースを・・・ CString DeleteFilePath = _T(""); myResult = MessageBox(_T("現在選択されているデータ(本体)を削除しますか?") ,_T("Deletion range confirmation"),MB_YESNOCANCEL); if(myResult == IDYES){ index = -1; while ((index = CFileListCreatorDlg::m_xcList.GetNextItem (index, LVNI_ALL | LVNI_SELECTED)) != -1) { CString FullPathString = CFileListCreatorDlg::m_xcList.GetItemText(index,2); FullPathString.Replace(_T ("\\"),_T("\\\\")); if ( FullPathString != "" ){ if ( PathFileExists(FullPathString) && FullPathString.Right(1) != _T("\\")) { //条件追加 DeleteFilePath = DeleteFilePath + FullPathString + _T('\0'); CFileListCreatorDlg::m_xcList.DeleteItem(index); }else{ m_xcList.GetNextItem(index++, LVNI_ALL | LVNI_SELECTED); } } index--; } DeleteFilePath = DeleteFilePath + _T('\0'); if ( DeleteFilePath == "" || DeleteFilePath == "\0\0" ) return -1; const wchar_t nc = L'\0'; _TCHAR result[256*1000]; if ( DeleteFilePath.GetLength() >= sizeof result /sizeof result[0]) return -1; const _TCHAR* cszPath = static_cast<const _TCHAR*>(DeleteFilePath); // DeleteFilePathの先頭から長さ分をresultにコピー std::copy(cszPath, cszPath+DeleteFilePath.GetLength(), result); SHFILEOPSTRUCT sfs; memset ( &sfs, 0, sizeof ( SHFILEOPSTRUCT ) ); sfs.fFlags = FOF_NOERRORUI | FOF_SIMPLEPROGRESS | FOF_ALLOWUNDO | FOF_NOCONFIRMATION; // ゴミ箱へ移動するが確認はしない FOF_ALLOWUNDO | FOF_NOCONFIRMATION; をつける sfs.wFunc = FO_DELETE; sfs.pFrom = cszPath; if ( 0 != SHFileOperation ( &sfs ) ) { //free( cszPath ); MessageBox(_T("ゴミ箱に移動できませんでした"),_T("SHFileOperation 失敗"),MB_OK); return -1; } return 0; } // resultを動的に確保してない点が気になりますが、問題なければ もうすぐ締め切りますm(_ _)m
- kumatti1
- ベストアンサー率60% (73/121)
>_tcscpy(cszPath, DeleteFilePath); // CString型→TCHAR型 strcpy系は終端文字の検索を行うので、複数のパスがセットされてると上手くコピーされないのでは。
お礼
ご指摘の通りでした。回答ありがとうございました!
- kumatti1
- ベストアンサー率60% (73/121)
>ブレークポイントおいてメモリダンプ見たらすぐわかんじゃねかな https://twitter.com/miyabi_inoue/status/482303397677129728 だそうです(・∀・)
補足
回答ありがとうございます。ブレイクポイントと設定するまでは分かるのですが、 メモリダンプの見方が分かりませんでした。マウスを変数の上に持って行って、値を 見る事はできますが。 _TCHAR cszPath[4096]; // TCHAR型 _tcscpy(cszPath, DeleteFilePath); // CString型→TCHAR型 ↑の部分を(1)(2)のように書き換えてみましたが、上手くいきません。 (1) int len = DeleteFilePath.GetLength(); _TCHAR *cszPath = (TCHAR*)malloc( sizeof( TCHAR ) * len ;) (2) size_t len = _tcsclen(DeleteFilePath); _TCHAR *cszPath = (TCHAR*)malloc( sizeof( TCHAR ) * len ;) ~ゴミ箱に移動する処理~ // "c:\\a.txt"と"C:\\b.txt" をゴミ箱へファイルを移動するサンプル (シェルエミュレート) SHFILEOPSTRUCT sfs; memset ( &sfs, 0, sizeof ( SHFILEOPSTRUCT ) ); sfs.fFlags = FOF_NOERRORUI | FOF_SIMPLEPROGRESS | FOF_ALLOWUNDO;// ゴミ箱へ移動の確認をする場合 FOF_ALLOWUNDO をつける; sfs.wFunc = FO_DELETE; sfs.pFrom = cszPath; //←ここがうまく行ってないんだと思います。 ~ゴミ箱に移動する処理~ free( cszPath ); (3) 念のため、トリムしてみましたが、意味がありませんでした。 CString FullPathString = CFileListCreatorDlg::m_xcList.GetItemText(index,2).Trim(); ___________________________________________________________________________________ いずれも・・・ if ( 0 != SHFileOperation ( &sfs ) ) { MessageBox(_T("ゴミ箱に移動できませんでした"),_T("SHFileOperation 失敗"),MB_OK); return 0; } ・・・"ゴミ箱に移動できませんでした"と画面にでます。 ただ、リストにフルパスを格納しているので、まずは一つのファイルを捨てる事から試して います。とりあえず「複数のパスがセットされてると上手くコピーされないのでは。」これは 置いておきたいです。 もう少し試行錯誤してみます。
お礼
ご親切にどうも有難うございました!自分では到底たどりつかないレベルでビックリしてます。 他にも応用が効きそうです。 ▼要らなくなる部分▼ const _TCHAR* cszPath = static_cast<const _TCHAR*>( DeleteFilePath ); // DeleteFilePathの先頭から長さ分をresultにコピー std::copy(cszPath, cszPath+DeleteFilePath.GetLength(), result); ▲要らなくなる部分▲ //この部分が要らなくなるのですね。最初分かりませんでした。 そして、教わった部分・・・ tstring buffer(static_cast<const _TCHAR*>( DeleteFilePath ), DeleteFilePath.GetLength()); const _TCHAR* cszPath = buffer.data(); ・・・を書いて、変数名を cszPath にそろえました。