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

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

CSting を TCHAR [] に変換したい。

Visual Sutdio 2010 , VC++ , MFC でファイルリスト一覧作成ソフトを作っている者です。 CSting 型の _T("~\0~\0\0") を TCHAR [] に変換したいです。 CSting 型の変数名は、DeleteFilePathです。 '\0' を他の文字に置換して確認した所、正しく入っています。 現在は、4096文字の文字列配列に入れています。 ゴミ箱に移動できる時とできない時があります。 _______________________________________________________________________________ ■現在のコード  index = -1;  while ((index = CFileListCreatorDlg::m_xcList.GetNextItem  (index, LVNI_ALL | LVNI_SELECTED)) != -1)  {   CString FullPathString = CFileListCreatorDlg::m_xcList.GetItemText(index,2);   if (FullPathString.Right(1) != _T("\\")){     ::SetFocus(::GetDlgItem(m_hWnd,IDC_LIST));    FullPathString.Replace(_T ("\\"),_T("\\\\"));    DeleteFilePath = DeleteFilePath + FullPathString + _T('\0');    CFileListCreatorDlg::m_xcList.DeleteItem(index);   }   index--;  }  DeleteFilePath = DeleteFilePath + _T('\0');  _TCHAR cszPath[4096];   // TCHAR型  _tcscpy(cszPath, DeleteFilePath);  // CString型→TCHAR型  SHFILEOPSTRUCT sfs;  memset ( &sfs, 0, sizeof ( SHFILEOPSTRUCT ) );  sfs.fFlags = FOF_NOERRORUI | FOF_SIMPLEPROGRESS | FOF_ALLOWUNDO;// ゴミ箱へ移動の確認をする場合 FOF_ALLOWUNDO をつける;  sfs.wFunc = FO_DELETE;  sfs.pFrom = cszPath;  if ( 0 != SHFileOperation ( &sfs ) )  {   MessageBox(_T("ゴミ箱に移動できませんでした"),_T("SHFileOperation 失敗"),MB_OK);   return 0;  } _________________________________________________________________________________________________________________________________________________ 5回に1回成功するので、不思議です。 ファイルのパスは、リストコントロールのアイテムに格納されていて、 削除したいアイテムを選択肢、Shift + Delete で、ゴミ箱に削除する ユーザー関数が呼び出されます。(ゴミ箱に移動するだけで、確認メッセージは出なくていいです。) 今まで、具体的した事を記すと以下のようになります。 cszPath = const_cast<LPTSTR>(static_cast<LPCTSTR>DeleteFilePath;  //ビルドエラー としたり、 _TCHAR cszPath[DeleteFilePath.GetLength()];  // TCHAR型 としたり、 TCHAR cszPath[256];  // TCHAR型 _tcscpy(cszPath, DeleteFilePath);  // CString型→TCHAR型 ・・・とやってみましたが、出来ません。 http://www.usefullcode.net/2006/12/post_13.html http://www5d.biglobe.ne.jp/~noocyte/Programming/Windows/WindowsTips.html#MoveToRecycleBin とかが参考になりそうです。 先程も書きましたが const _TCHAR cszPath[] = _TEXT ( "C:\\a.txt\0C:\\b.txt\0" ); の代入がうまく行きません。 ____________________________________________________________________________________________________________________________________ http://sysneitf.ifdef.jp/shell_filestotrash.html 以下、参考にした部分 // 複数ある場合は、パスを'\0'で区切る。終端は、'\0''\0'である必要がある  const _TCHAR cszPath[] = _TEXT ( "C:\\a.txt\0C:\\b.txt\0" ); // "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;  if ( 0 != SHFileOperation ( &sfs ) )  {   MessageBox ( NULL,   _TEXT ( "SHFileOperation 失敗" ),   _TEXT ( "エラー" ),   MB_OK | MB_ICONSTOP );  } どなたか、お教え下さると嬉しいですm(_ _)m

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

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

  • 構造体を動的に確保&解放

    度々お世話になってます。 構造体を動的に確保し、処理後メモリーリークが起こらないように解放したいです。 item を m_xcList.GetItemCount() 個、宣言したいです。 ご教授願いたいです。 ▼ソースの一部抜粋▼ void CFileListCreatorDlg::SameItemCheck(CString mySwitch) {  LVITEM  lvi;  int   index = 0;  UpdateData();  lvi.mask = LVIF_TEXT;  CString FullPathString;  CString myFileName;  index = 0;  while (index < CFileListCreatorDlg::m_xcList.GetItemCount()){   lvi.iItem = index;   lvi.iSubItem = 0;      lvi.pszText = const_cast<LPTSTR>(static_cast<LPCTSTR>(_T("")));   CFileListCreatorDlg::m_xcList.SetItem(&lvi);   index++;  }  //0:ファイル重複識別ナンバー 1:通し番号 2:フルパス 3:ファイル名 4:おおよそのデータサイズ 5:データサイズ 6:修正日 7:修正時間 8:備考欄 9:書式情報  //ファイル名、ファイル容量、修正日時により、重複チェック  struct item  {   CString RepetitionNum; //ファイル重複識別ナンバー   //int  Num;  //通し番号   CString FullPath; //ファイルパス   CString FileName; //ファイル名   //CString ApproximateByte; //おおよそのデータサイズ//バイト   CString AccurateByte;  //実際のデータサイズ//実バイト      //TCHAR ModifyDate[20];  //修正日   //CTime ModifyTime;  //修正時間      CString ModifyTime;  //修正時間      //TCHAR RemarksColumn[100];  //備考欄  };  //http://www-watt.mech.eng.osaka-u.ac.jp/~tasai/cp/lec1.html ← プログラム5を参考にしました。  struct item *array;  /* メモリの確保 */  array = (struct item*)malloc(sizeof(struct item)*(CFileListCreatorDlg::m_xcList.GetItemCount()-1));  if (array == NULL) {   StatusStringSet(_T("memory allocation error\r\n"),0,TRUE);   exit(EXIT_FAILURE);  }  //const int itemNum = sizeof item /sizeof array[0];  int i;  for (i = 0; i < CFileListCreatorDlg::m_xcList.GetItemCount(); i++) //初期化  {   array[i].RepetitionNum = _T(""); //ファイル重複識別ナンバー   array[i].FileName = _T(""); //ファイル名   array[i].AccurateByte = _T(""); //データサイズ   array[i].ModifyTime = _T(""); //修正時間  } int cc;  int dd;  cc = 1;  dd = 1;  if(mySwitch == _T("SameItemCheck_BY_FileName")){   //0:ファイル重複識別ナンバー 1:通し番号 2:フルパス 3:ファイル名 4:おおよそのデータサイズ 5:データサイズ 6:修正日 7:修正時間 8:備考欄 9:書式情報   StatusStringSet(_T("ファイル名により、重複チェック"),0,FALSE);   index = 0;   while (index < CFileListCreatorDlg::m_xcList.GetItemCount()){    array[index].RepetitionNum = _T("");    FullPathString = CFileListCreatorDlg::m_xcList.GetItemText(index,2);    if(FullPathString != _T("")){     array[index].FileName = FullPathToFileName(FullPathString);    }    for (dd = 0; dd <= index-1; dd++){     if (array[dd].FileName == array[index].FileName){      if (array[index].RepetitionNum != _T("")){       array[dd].RepetitionNum = array[index].RepetitionNum;       //" 重複番号欄に既に重複Noが、入っているとき"      }else{       //cc // " インクリメントcc"        CString str;        if (cc>=INT_MAX){         str = _T("MAX-Value");        }else{         str.Format(_T("%d"),cc);        }        array[index].RepetitionNum = const_cast<LPTSTR>(static_cast<LPCTSTR>(str));        if (array[dd].RepetitionNum != array[index].RepetitionNum){         cc++;        }      }      lvi.iItem = index;      lvi.iSubItem = 0;         lvi.pszText = const_cast<LPTSTR>(static_cast<LPCTSTR>(array[index].RepetitionNum));      CFileListCreatorDlg::m_xcList.SetItem(&lvi);      UpdateData(FALSE);            lvi.iItem = dd;      lvi.iSubItem = 0;         lvi.pszText = const_cast<LPTSTR>(static_cast<LPCTSTR>(array[index].RepetitionNum));      CFileListCreatorDlg::m_xcList.SetItem(&lvi);      UpdateData(FALSE);     }    }    index++;    UpdateData(FALSE);   }  }else if(mySwitch == _T("SameItemCheck_By_DataSize")){   //省略  } } ▲ソースの一部抜粋▲ コンパイルは通るのですが、実行時に↓のエラーがでます。 どこの部分ががおかしいのでしょうか??  ▼エラーメッセージ▼  FileListCreator.exe の 0x00f08ac1 でハンドルされていない例外が発生しました: 0xC0000005: 場所 0xcdcdcdbd を読み込み中にアクセス違反が発生しました。  void Empty() throw()  {   CStringData* pOldData = GetData();   IAtlStringMgr* pStringMgr = pOldData->pStringMgr;   if( pOldData->nDataLength == 0 )   {    return;   }   if( pOldData->IsLocked() )   {    // Don't reallocate a locked buffer that's shrinking    SetLength( 0 );   }   else   {    pOldData->Release();    CStringData* pNewData = pStringMgr->GetNilString();    Attach( pNewData );   }  }  ▲エラーメッセージ▲ 汎用的なコードをお教え願いたいです。宜しくお願いします。

  • フォルダの削除について

    Cでのフォルダの削除方法が分からず困っています。 ファイルの削除は"remove()"で行うことができましたが、フォルダは同じ方法ではできないようです。 No.394869 の質問を参考にして"SHFileOperation()"を使用してみたのですが、エラー担ってしまいました。(Access Violation) "SHFILEOPSTRUCT"の値の設定(ハンドルなど)がうまくいっていないのかな?とも思ったのですが、 どうすればよいのかわかりません。 別の方法があればそれでもいいですし、"SHFileOperation()"の使い方(ハンドルの設定など)を知りたいのでよろしくお願いします。 ちなみに、今は以下の方法でやっていました。 フォルダ内(testfolder)は空の状態です。 ******************************************** SHFILEOPSTRUCT shfileop; /* ファイルの削除 */ shfileop.hwnd = NULL; shfileop.wFunc = FO_DELETE; shfileop.pFrom = "C:\\TEST\\testfolder"; shfileop.fFlags = FOF_SIMPLEPROGRESS|FOF_NOCONFIRMATION; SHFileOperation(&shfileop);

  • VC++2005で、CString型に16進文字列を入れたいのですが・・

    VC++2005で、CString型に16進文字列を入れたいのですが・・・ 次のようなエラーが出ます。 void ATL::CStringT<BaseType,StringTraits>::Format(const wchar_t *,...)' : 1 番目の引数を 'const char [5]' から 'const wchar_t *' に変換できません。 プログラムは次の通りです。 CString strBuff; CString strWork; TCHAR tszBuff[80]; UINT unLength; UINT un1; unLength = 5; strBuff = "12345"; _tcscpy(tszBuff, strBuff); strWork = ""; for(un1 = 0; un1 < unLength; un1++) { strWork = strWork + strBuff.Format("%02x", tszBuff[un1]); ←ここにエラーがあると言われています。 } 結果は、strWorkに、"3132333435"となるようにしたい! ネットで探したら、 >UNICODEを使われているのだと思われます。 >T("")マクロを使ってワイドキャラクタに変換するように指示すれば動くと思います。 とあったので、 strWork = strWork + strBuff.Format(_T("%02x"), tszBuff[un1]); としてみたのですが、 二項演算子 '+' : 型 'void' の右オペランドを扱う演算子が見つかりません (または変換できません)。 というエラーが表示されました。 VC++6.0を半年かじり、今日、初めてVC++2005に触った程度の初心者です。 どなたか助言を頂ければ幸いです。 環境  Windows XP Pro SP3  Visual C++ 2005(MFC) 以上、よろしくお願いします。

  • ファイルやフォルダをごみ箱に移動 その2

    直下の質問「ファイルやフォルダをごみ箱に移動」をさせていただいた者です。 「ファイルやフォルダをごみ箱に移動」を行うActiveX DLLを作成して、無事動作させることができました。が、新しい問題が発生してしまいました。 作成したルーチンは、以下の通りです。 ----- Public Sub GoToTrash(inStrItemNames As String, Optional inBlnConfirm As Boolean) Dim ShellOp As SHFILEOPSTRUCT Dim flg As Integer ' 確認メッセージの表示? If IsMissing(inBlnConfirm) Then inBlnConfirm = False If inBlnConfirm Then flg = FOF_ALLOWUNDO Else flg = FOF_ALLOWUNDO Or FOF_NOCONFIRMATION End If With ShellOp .hwnd = 0 .wFunc = FO_DELETE .pFrom = inStrItemNames .fFlags = flg End With ' ごみ箱へ削除実行 SHFileOperation(ShellOp) End Sub ----- これをActiveX化して、ASPから呼び出すと、ちゃんと動作して、指定されたファイルはごみ箱に直行します。しかし、存在しないファイルなどが指定されると、たとえ、FOF_NOCONFIRMATIONを指定したとしても、確認のDialogBoxが表示されてしまうようです。(WSHで確認しました) こうなると、ASPではスクリプトエンジンが処理を中断してしまうようで、以降再起動しない限り、ASPページが全く表示されなくなってしまいます。 なにか良い手段は無いでしょうか?

  • ファイルやフォルダをごみ箱へ移動

    ASPの処理で、ファイルを削除する必要があるのですが、誤動作の保険のためにファイルを直接削除せず、一旦ごみ箱に移動させたいと思っています。 いろいろ検索したのですが、決定打が未だ見つかりません。 今までの調べでは、SHFILEOPSTRUCT構造体にオペレーションをセットして、SHFileOperation関数を呼び出すActiveX DLLを自作して、ASPから使用するしか方法がないようです。 FileSystemObject::MoveFile を使用して、\RECYCLED へ移動すれば良いかとも考えたのですが、質問:「GetFolder や GetFile でASPの処理がストップ」と同様の現象で処理が戻ってきません。 何かもっと手軽な方法をお知りの方がいましたら、教えてください。

  • ファイルやフォルダのごみ箱への移動 2

    ファイル(もしくはフォルダ)を一つ選択してごみ箱に捨てるとき、「いいえ」を押したら別の処理をさせようとしているのですが、作ってみた関数だと上手くいきません。 どういうわけか常に 0 が返ってきます。 --------------------------------- Public Function FileToDust(FName As String) As Long 'ファイルをごみ箱へ送る 'FName --- ファイル、フォルダ名を入れる文字列変数   Dim FOS As SHFILEOPSTRUCT   With FOS     .hWnd = 0     .wFunc = FO_DELETE     .pFrom = FName     .fFlags = FOF_ALLOWUNDO   End With   FileToDust = SHFileOperation(FOS) End Function --------------------------------------- どこが悪いんでしょうか。本来なら、処理が中断されれば 0 以外が返ってくるらしいのですが…… 0 が返ってきたとき成功したと思って前回の質問をすぐに打ち切ってしまったので、もう一度質問させていただきます。 前回の質問 http://oshiete1.goo.ne.jp/kotaeru.php3?q=466239 よろしくお願いします。 ---------------- 開発環境 VB6.0SP5 WinME

  • realloc の使い方について教えてください!

    http://okwave.jp/qa/q7445404.html で質問した者です。 【1】 あれから試行錯誤して、new と delete を使うことを試みました。まずOnInitDialog()で、サイズが0の 構造体を生成して、prevDataを毎回 delete してから、new してたのですが、UNDOは出来ましたが、REDOが できません。 【2】 ちなみに、前回質問時の m_xcList を(リストコントロールごと)退避して、一個前と 今回のリスト全体を置き換える方法は、outList->DeleteAllItems();の後、どうやっても 復元できないので、やめました。 【3】 今回の質問は、構造体をreallocで、その都度上書きしたい(する方針に変えました)です。 できればメモリーが足りない場合は、エラー処理もしたいと考えています。今は都合上、構造体要素は すべて、String型で定義しています。後で、TCHARに直します。 今の状態は、malloc_Func()が2度呼ばれると「ハンドルされていない例外が発生しました」と でて、止まります。構造体配列のサイズがうまく取れていないと思っています。 →prevData[ItemNo].RepetitionNum = inData; で止まります。  typedef struct any {   //int *i;   CString RepetitionNum; //ファイル重複識別ナンバー   CString Num;  //通し番号   CString FullPath; //ファイルパス   CString FileName; //ファイル名   CString ApproximateByte; //おおよそのデータサイズ//バイト   CString AccurateByte;  //実際のデータサイズ//実バイト   CString ModifyDate;  //修正日   CString ModifyTime;  //修正時間   CString RemarksColumn;  //備考欄   CString FormatDataStr; //書式情報   //item():   //~item();  }ListItemStruct;  ListItemStruct *prevData;  ListItemStruct *nowData;  ListItemStruct *workData; void malloc_Func(int ItemCount,CString targetName); //このユーザー関数内でreallocしています。  //以下の3つのグローバル変数は、最後の GetItemCount() で取得してINDEXを退避しています。  int LastPrevItemCount;  int LastNowItemCount;  int LastWorkItemCount;  //http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1117611511  //http://blogs.wankuma.com/jitta/archive/2008/12/16/164045.aspx //ユーザー関数内で、分岐して、各ポインターに合わせた処理を行うようになっています。 //一箇所に纏めたかっただけです。 void CFileListCreatorDlg::malloc_Func(int ItemCount,CString targetName){  if (targetName=_T("prevData")){   {    int ItemNo = 0;    int SubItemNo = 0;    int err = 0;    ItemNo = 0;     while ( ItemNo < ItemCount ) //ItemCount分、構造体配列をreallocします。     {          //if( ItemCount == 0 ) {//この↓部分はアプリ起動時一回目にしか実行されないようにOnInitDialog()に記述しました。      // prevData = (ListItemStruct*)malloc(sizeof(ListItemStruct));      // if (prevData == NULL) { return; }      //}else{       ListItemStruct* dummy = (ListItemStruct*)realloc(prevData,sizeof(ListItemStruct)*ItemNo+1);       if (dummy == NULL) {        if (prevData != NULL){         free(prevData);         prevData = NULL;        }       }else{        prevData = dummy;       }      //}      SubItemNo=0;      while (SubItemNo<=9){       //if (!err)       {        CString inData;        inData = CString(m_xcList.GetItemText(ItemNo, SubItemNo));              switch (SubItemNo){         case 0:          prevData[ItemNo].RepetitionNum = inData;          break;         case 1:          prevData[ItemNo].Num = inData;          break;         case 2:          prevData[ItemNo].FullPath = inData;          break;         case 3:          prevData[ItemNo].FileName = inData;          break;         case 4:          prevData[ItemNo].ApproximateByte = inData;          break;         case 5:          prevData[ItemNo].AccurateByte = inData;          break;         case 6:          prevData[ItemNo].ModifyDate = inData;          break;         case 7:          prevData[ItemNo].ModifyTime = inData;          break;         case 8:          prevData[ItemNo].RemarksColumn = inData;          break;         case 9:          prevData[ItemNo].FormatDataStr = inData;          break;        }              CFileListCreatorDlg::StatusStringSet(_T("UNDOデータ 退避中"),0,FALSE);//ダイアログ上のテキストに状態を記しています。       }       SubItemNo++;      }      ItemNo++;     }   } } プログラムが終わるときに解放しています。 free(prevData); prevData = NULL; free(nowData); nowData = NULL; free(workData); workData = NULL; 参考書も見てみたのですが、分かりません。まずは一応動く程度でも構いませんので、 教えてくださると嬉しいです。宜しくお願いします。

  • 2日以前のファイルを削除するワイルドカーの指定方法について教えてください。

    現在日時から2日以前のファイルを削除対象とします。 ファイル名は以下のようになっています。 20081112162021_aaa_bbb.tmp 20081113162021_aaa_ccc.tmp 20081114162021_aaa_ddd.tmp 20081115162021_aaa_eee.tmp 2日以前を削除なので、11月12日と11月13日のファイルが 消えてくれればOKです。 削除対象となるファイル数は、多いと思うので、 1ファイルずつ消すという方法(DeleteFileやRemove)は、 考えていません。 以下のサンプルを見つけたのですが、 ワイルドカード指定で、2日以前のファイルだけを削除対象する ワールドカードの書き方が分からないので教えてください。 #include <windows.h> int main() { SHFILEOPSTRUCT sfo = { 0 };   sfo.wFunc = FO_DELETE; sfo.pFrom = TEXT( "D:\\Temp\\*.tmp" ); sfo.fFlags = FOF_NOCONFIRMATION; ::SHFileOperation( &sfo ); return 0; } C++ Windows2003Server

  • Unicodeのファイル読み込みがうまくいきません。。

    下のようなコードで読もうとしているんですが、どうしても文字化けしてしまいます。原因が何なのかさっぱりわかりません。。 分かる方どうかお願いします!開発環境はVC++.NETです。 FILE* fin; wchar_t c; CString ss; if( (fin = fopen( "temp.txt", "r" )) == NULL ){ AfxMessageBox("temp.txtファイルオープンエラー"); exit(1); } fgetws( &c, 2, fin ); ss += c; AfxMessageBox(ss);

  • template 参照 operator について

    「ゲームプログラマになる前に覚えておきたい技術」という書籍を読みながらC++でプログラミングの学習をしているのですが、template class と 参照 と operator の組み合わさったクラスでわからないところがあります。 自分で出来る限り調べてみましたが、解決できなかったので、答えていただけると幸いです。 Cの学習はひととおり済んでおりますが、まだC++は学習を始めたばかりなので理解が浅いです。 質問内容にいたらない点があるとは思いますが、お願いします。 以下のようなクラス定義文がありました。 template< class T > class Array2D{ public: Array2D() : mArray( 0 ){} ~Array2D(){ delete[] mArray; mArray = 0; } void setSize( int size0, int size1 ){ mSize0 = size0; mSize1 = size1; mArray = new T[ size0 * size1 ]; } T& operator()( int index0, int index1 ){ return mArray[ index1 * mSize0 + index0 ]; } const T& operator()( int index0, int index1 ) const { return mArray[ index1 * mSize0 + index0 ]; } private: T* mArray; int mSize0; int mSize1; }; この定義文の以下の部分 T& operator()( int index0, int index1 ){ return mArray[ index1 * mSize0 + index0 ]; } において、T&という記述がなければ、()という演算子のはたらきを再定義していて、 mArrayを2次元的に利用できるように値を返しているように見えるのですが、 T&がつくことによって、なにがどうなっているのでしょうか。 それと、参照というのは、利用するときには必ず初期化が必要、と学習したのですが、 この場合、初期化の処理になっているのでしょうか。 今までに出てきた参照では、簡単な例でいうと int n; int& m = n; というように、型名&別名=参照先 と、即初期化して使っていました。 これなら初期化されているのはわかりますが、今回のように、 「別名」の部分がoperatorになっていると、どのアドレスが「別名」が指すアドレスになるのでしょうか。 さっぱりわかりません。 質問の連続になってしまって申し訳ありません。 ほんとに困ってます。 おねがいします。

専門家に質問してみよう