• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:CSting を TCHAR [] に変換したい。)

CStingをTCHAR[]に変換したい - VC++でファイルリスト一覧作成ソフトを作成

このQ&Aのポイント
  • CSting型の_T("~\0~\0\0")をTCHAR[]に変換したいです。
  • 現在は、4096文字の文字列配列にCSting型の変数DeleteFilePathを入れています。
  • ファイルのパスをゴミ箱に削除するために、SHFileOperation関数を使用しています。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.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; } }

psychang
質問者

お礼

ご親切にどうも有難うございました!自分では到底たどりつかないレベルでビックリしてます。 他にも応用が効きそうです。 ▼要らなくなる部分▼ 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 にそろえました。

その他の回答 (3)

回答No.3

_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; } }

psychang
質問者

補足

できました!ありがとうございます! 一応、ソースを・・・ 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)
回答No.2

>_tcscpy(cszPath, DeleteFilePath);  // CString型→TCHAR型 strcpy系は終端文字の検索を行うので、複数のパスがセットされてると上手くコピーされないのでは。

psychang
質問者

お礼

ご指摘の通りでした。回答ありがとうございました!

  • kumatti1
  • ベストアンサー率60% (73/121)
回答No.1

>ブレークポイントおいてメモリダンプ見たらすぐわかんじゃねかな https://twitter.com/miyabi_inoue/status/482303397677129728 だそうです(・∀・)

psychang
質問者

補足

回答ありがとうございます。ブレイクポイントと設定するまでは分かるのですが、 メモリダンプの見方が分かりませんでした。マウスを変数の上に持って行って、値を 見る事はできますが。 _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; } ・・・"ゴミ箱に移動できませんでした"と画面にでます。 ただ、リストにフルパスを格納しているので、まずは一つのファイルを捨てる事から試して います。とりあえず「複数のパスがセットされてると上手くコピーされないのでは。」これは 置いておきたいです。 もう少し試行錯誤してみます。

関連するQ&A