dポイントプレゼントキャンペーン実施中!

テキストファイルの各行の文字列を、コンボBoxに表示させたい

現在VC++ MFCの勉強をしております。(MFCに拘ってはおりません)

下のテキストファイル"D:\data.txt" (Shift_JIS)から
(内容)
田中さん
斉藤さん
吉田さん

CFile の Read で一行ずつ読み込んで、CStringArrayを使って
コンボBox に Insert したいと思っています。

下記のコードについてですが。
BOOL CAddDialog::OnInitDialog()
{
CDialog::OnInitDialog();

// TODO: ここに初期化を追加してください
TCHAR* pszFileName = L"d:\\data.txt";
CFileException fileException;

CFile cFile;

int ret;

char buffLine[256] ;

CStringArray cStrComboArr ; // リスト

ret = cFile.Open( pszFileName , CFile::modeRead | CFile::shareDenyNone , &fileException );
if ( ret == false )
{
AfxMessageBox( L"ファイルが読込めません。" );
return 1;
}

while ( (ret = cFile.Read( &buffLine , 256 )) != 0 )
{
cStrComboArr.Add( buffLine ); /* ここでビルドエラー */
}
cFile.Close();

// コンボboxに入れる
CComboBoxEx* pCombo =
(CComboBoxEx*) GetDlgItem( IDC_COMBOBOXEX1 );
COMBOBOXEXITEM cbi ;
cbi.mask = CBEIF_TEXT;

for ( int i = 0; i < cStrComboArr.GetCount(); i++ )
{
cbi.iItem = i;
cbi.pszText = (LPTSTR)(LPCTSTR) cStrComboArr.ElementAt(i) ; // 「'CString' から 'LPWSTR' に変換できません」から。
cbi.cchTextMax = 256;
pCombo->InsertItem( &cbi );
}

return TRUE; // return TRUE unless you set the focus to a control
// 例外 : OCX プロパティ ページは必ず FALSE を返します。
}

cStrComboArr.Add( buffLine ); の部分でエラー表示は、
「INT_PTR CStringArray::Add(LPCTSTR)' : 1 番目の引数を 'char [256]' から 'LPCTSTR' に変換できません。」です。

根本的にやり方が間違っているのか、もう少しのところなのか、
ズバッとご指摘いただけないでしょうか。

宜しくお願いします。

OS : Vista Home Premium
VS 2008 pro

A 回答 (3件)

>コンボボックスに入れるときは


>CComboBoxExの親クラスのCComboBoxのメンバ関数が使えるので、
>文字列を格納するだけであれば、AddStringやInsertStringで十分ではないでしょうか。
は使えないようですね。ASSERT(FALSE);がモロ書いてありました。

fgetsをつかった場合はこんな感じ
※インデントの全角空白を使っています。コピペは注意してください。

  TCHAR* pszFileName = _T("d:\\data.txt");
  CStringArray cStrComboArr ;
#if 0
  setlocale(LC_ALL, ".ACP");

  TRY
  {
    CStdioFile cFile(pszFileName , CFile::modeRead | CFile::shareDenyNone);
    CString strLine;
    while (cFile.ReadString(strLine)) {
      cStrComboArr.Add(strLine);
    }
    cFile.Close();
  }
  CATCH (CFileException, e)
  {
    AfxMessageBox(_T("ファイルの読み込み失敗!"));
  }
  END_CATCH
#else
  FILE* fp = NULL;
  if (_tfopen_s(&fp, pszFileName, _T("r")) != 0) {
    AfxMessageBox(_T("ファイルのオープン失敗!"));
  }
  char szLine[256];
  while (fgets(szLine, _countof(szLine), fp) != NULL) {
    cStrComboArr.Add(CString(szLine));
  }
  if (fclose(fp) != 0) {
    AfxMessageBox(_T("ファイルのクローズ失敗!"));
  }
#endif

  CComboBoxEx* pComboBox = (CComboBoxEx*)this->GetDlgItem(IDC_COMBOBOXEX1);
  COMBOBOXEXITEM cbi = {0};
  cbi.mask = CBEIF_TEXT;
  for (INT_PTR i = 0; i < cStrComboArr.GetCount(); ++i, ++cbi.iItem)
  {
    cbi.pszText = const_cast<LPTSTR>(static_cast<LPCTSTR>(cStrComboArr[i]));
    cbi.cchTextMax = cStrComboArr[i].GetLength();
    pComboBox->InsertItem(&cbi);
  }

この回答への補足

素晴しい!

成功しました。
bluecampusさんのおかげでした。
今後、自分で解決できるよう、基礎に戻って習得していきたいと思います。

また質問すると思いますが、brosisを見かけたら宜しくお願いします。

補足日時:2010/03/12 10:43
    • good
    • 0
この回答へのお礼

>  while (fgets(szLine, _countof(szLine), fp) != NULL) {
>    cStrComboArr.Add(CString(szLine));
>  }
CStringのコンストラクタを使うとはこのことだったのですね。

こんなに細かく書いて頂いて、ホントに感謝です。

しかし、
>  for (INT_PTR i = 0; i < cStrComboArr.GetCount(); ++i, ++cbi.iItem)
>  {
>    cbi.pszText = const_cast<LPTSTR>(static_cast<LPCTSTR>(cStrComboArr[i]));
>    cbi.cchTextMax = cStrComboArr[i].GetLength();
>    pComboBox->InsertItem(&cbi);
>  }
この箇所の手法は、今の私には未だ理解するのに時間がかかりそうです。。

お礼日時:2010/03/11 23:29

setlocaleは関数内で書かないとだめです。



#include <xxxx.h>
setlocale(LC_ALL, ".ACP");

とかいても当然エラーです。
読み込む直前で書いてもよいのですが、
・何度も読み込むことがある
・setlocaleを固定してしまって問題ない(場合によって切り分ける必要がない)
のであれば、CXXXAppクラスのInitInstanceメソッドに記述すればいいです。
場所は
>SetRegistryKey
と記述がある次の行あたりで。


ちなみにMSDN フォーラムの蒼の洞窟は私です。
>「 CStdioFileを使わず、fopen,fgetsを使って、char型配列に文字列を読み込み、 CStringクラスを使ってUnicodeに変換する場合は、setlocaleは必要ないかもしれません。」
とは、char型からCStringへキャストすればいい?ということでしょうか?
ヒントをいただけたらうれしいです。

については、キャストというわけではなくCStringのコンストラクタを使って変換するということです。
    • good
    • 0
この回答へのお礼

>ちなみにMSDN フォーラムの蒼の洞窟は私です。
そうでしたか。世間は狭いですね。

>については、キャストというわけではなくCStringのコンストラクタを使って変換するということです。
私は、このことがピンと来ないということは、もっと基礎からやり直さないといけません。

お礼日時:2010/03/11 23:20

まず、CFile::Readでは1行ごとに読み込めません。


CStdioFileクラスのReadStringをつかうとCString型でやり取りできます。
(setlocaleが必要)
http://msdn.microsoft.com/ja-jp/library/x5t0zfyf …


>cStrComboArr.Add( buffLine ); の部分でエラー表示は、
>「INT_PTR CStringArray::Add(LPCTSTR)' : 1 番目の引数を 'char [256]' から 'LPCTSTR' に変換できません。」です。
CStringのコンストラクタを使ってみては。
ただし、buffLine が'\0'で終端しているという保証はないでしょうけど。

コンボボックスに入れるときは
CComboBoxExの親クラスのCComboBoxのメンバ関数が使えるので、
文字列を格納するだけであれば、AddStringやInsertStringで十分ではないでしょうか。
    • good
    • 0
この回答へのお礼

bluecampusさん
ご回答ありがとうございます。

>まず、CFile::Readでは1行ごとに読み込めません。
>CStdioFileクラスのReadStringをつかうとCString型でやり取りできます。
実は、CFileを使う前、CStdioFileを試していましたが、
「Unicode 文字セットを使用する」を設定している為、文字化けしていました。

>(setlocaleが必要)
とは、どのソースファイルのどの位置に書けばいいのか
アドバイスいただけないでしょうか。

msdn > forum > VC++ で同じような質問をしたのですが、
どなたからも回答頂けませんでしたので、okwaveにきました。

宜しくお願いします。

お礼日時:2010/03/11 16:06

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!