- ベストアンサー
CStingをTCHAR[]に変換したい - VC++でファイルリスト一覧作成ソフトを作成
επιστημη(@episteme)の回答
// 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; } }
関連する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・C++・C#
- フォルダの削除について
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);
- ベストアンサー
- C・C++・C#
- 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) 以上、よろしくお願いします。
- ベストアンサー
- C・C++・C#
- ファイルやフォルダをごみ箱に移動 その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ページが全く表示されなくなってしまいます。 なにか良い手段は無いでしょうか?
- ベストアンサー
- Microsoft ASP
- ファイルやフォルダをごみ箱へ移動
ASPの処理で、ファイルを削除する必要があるのですが、誤動作の保険のためにファイルを直接削除せず、一旦ごみ箱に移動させたいと思っています。 いろいろ検索したのですが、決定打が未だ見つかりません。 今までの調べでは、SHFILEOPSTRUCT構造体にオペレーションをセットして、SHFileOperation関数を呼び出すActiveX DLLを自作して、ASPから使用するしか方法がないようです。 FileSystemObject::MoveFile を使用して、\RECYCLED へ移動すれば良いかとも考えたのですが、質問:「GetFolder や GetFile でASPの処理がストップ」と同様の現象で処理が戻ってきません。 何かもっと手軽な方法をお知りの方がいましたら、教えてください。
- ベストアンサー
- Microsoft 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
- ベストアンサー
- Visual Basic
- 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; 参考書も見てみたのですが、分かりません。まずは一応動く程度でも構いませんので、 教えてくださると嬉しいです。宜しくお願いします。
- ベストアンサー
- C・C++・C#
- 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
- 締切済み
- C・C++・C#
- 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);
- ベストアンサー
- C・C++・C#
- 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になっていると、どのアドレスが「別名」が指すアドレスになるのでしょうか。 さっぱりわかりません。 質問の連続になってしまって申し訳ありません。 ほんとに困ってます。 おねがいします。
- ベストアンサー
- C・C++・C#
お礼
ご親切にどうも有難うございました!自分では到底たどりつかないレベルでビックリしてます。 他にも応用が効きそうです。 ▼要らなくなる部分▼ 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 にそろえました。