• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:テキストファイルの各行の文字列を、コンボBoxに表示させたい)

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

このQ&Aのポイント
  • VC++ MFCでテキストファイルから各行の文字列をコンボBoxに表示させる方法について質問があります。
  • 現在VC++ MFCの勉強をしており、テキストファイルから一行ずつ読み込んでコンボBoxに表示したいと考えています。
  • しかし、特定の箇所でビルドエラーが発生しており、解決方法がわかりません。お手数ですが、ご教示いただけますと幸いです。

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

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

brosis
質問者

お礼

>  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); >  } この箇所の手法は、今の私には未だ理解するのに時間がかかりそうです。。

brosis
質問者

補足

素晴しい! 成功しました。 bluecampusさんのおかげでした。 今後、自分で解決できるよう、基礎に戻って習得していきたいと思います。 また質問すると思いますが、brosisを見かけたら宜しくお願いします。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (2)

回答No.2

setlocaleは関数内で書かないとだめです。 #include <xxxx.h> setlocale(LC_ALL, ".ACP"); とかいても当然エラーです。 読み込む直前で書いてもよいのですが、 ・何度も読み込むことがある ・setlocaleを固定してしまって問題ない(場合によって切り分ける必要がない) のであれば、CXXXAppクラスのInitInstanceメソッドに記述すればいいです。 場所は >SetRegistryKey と記述がある次の行あたりで。 ちなみにMSDN フォーラムの蒼の洞窟は私です。 >「 CStdioFileを使わず、fopen,fgetsを使って、char型配列に文字列を読み込み、 CStringクラスを使ってUnicodeに変換する場合は、setlocaleは必要ないかもしれません。」 とは、char型からCStringへキャストすればいい?ということでしょうか? ヒントをいただけたらうれしいです。 については、キャストというわけではなくCStringのコンストラクタを使って変換するということです。

brosis
質問者

お礼

>ちなみにMSDN フォーラムの蒼の洞窟は私です。 そうでしたか。世間は狭いですね。 >については、キャストというわけではなくCStringのコンストラクタを使って変換するということです。 私は、このことがピンと来ないということは、もっと基礎からやり直さないといけません。

全文を見る
すると、全ての回答が全文表示されます。
回答No.1

まず、CFile::Readでは1行ごとに読み込めません。 CStdioFileクラスのReadStringをつかうとCString型でやり取りできます。 (setlocaleが必要) http://msdn.microsoft.com/ja-jp/library/x5t0zfyf%28VS.80%29.aspx >cStrComboArr.Add( buffLine ); の部分でエラー表示は、 >「INT_PTR CStringArray::Add(LPCTSTR)' : 1 番目の引数を 'char [256]' から 'LPCTSTR' に変換できません。」です。 CStringのコンストラクタを使ってみては。 ただし、buffLine が'\0'で終端しているという保証はないでしょうけど。 コンボボックスに入れるときは CComboBoxExの親クラスのCComboBoxのメンバ関数が使えるので、 文字列を格納するだけであれば、AddStringやInsertStringで十分ではないでしょうか。

brosis
質問者

お礼

bluecampusさん ご回答ありがとうございます。 >まず、CFile::Readでは1行ごとに読み込めません。 >CStdioFileクラスのReadStringをつかうとCString型でやり取りできます。 実は、CFileを使う前、CStdioFileを試していましたが、 「Unicode 文字セットを使用する」を設定している為、文字化けしていました。 >(setlocaleが必要) とは、どのソースファイルのどの位置に書けばいいのか アドバイスいただけないでしょうか。 msdn > forum > VC++ で同じような質問をしたのですが、 どなたからも回答頂けませんでしたので、okwaveにきました。 宜しくお願いします。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 文字列について

    textファイルをいくつかに分割して保存しようと思い、以下のプログラムを作りましたが、うまくいきません。 予定では "0000.txt", "0001.txt", ....と文字列を生成するはずです。 #include <stdio.h> #include <string.h> #define LENGTH 4 //番号の桁数 void filename(int n) {    char name[LENGTH +4 +1];    char text[5] = ".txt";    int i;    for(i = 0; i <= LENGTH; i++)       name[i] = '0';    i = LENGTH;    //自然数を文字列に変換    do{       name[i] = (char)(n%10 + 48);       i--;       n /= 10;    }while(n != 0 && i >= 0);    strcat(name, text);    printf("filename:%s", name); } int main(void) {    int i;    for(i = 0; i < 5; i++){       filename(i);       printf("\n");    }    return 0; } 実行結果は filename:00000@.txt filename:00001.txt filename:00002.txt filename:00003.txt filename:00004.txt このように、文字化けしています。 何が原因なのでしょうか。 よろしくお願いします。

  • (MFC)コンボボックスの値を数値比較

    VC++2005のMFCにてアプリケーションを作成しています。 コンボボックス(Ctrl変数:m_xcStMonth)に入力された値の、 正常値入力チェックとして、「1」から「12」までの数値ならtrue、 それ以外の数値及び文字列ならfalseを返す機能を実装したいのですが、 下記プログラムだと、「2」を入力しても、比較関数(1)(2)の戻り値として、 (1)RetMonth1には正常値「1」を返すのですが、 (2)RetMonth2にも誤り値「1」を返してしまいます。 原因として、「2」と「12」を比較した際に、 それぞれ一文字目の「2」と「1」を比較してしまうので、 誤り値を返してしまうようです。 下記が問題のソースコードです。 案1が比較関数にstrcpy_s()を使用した場合、 案2が比較関数CString::Compare()を使用した場合です。 両方において、RetMonth2に誤った戻り値を返しています。 もし何か良い改善策、より効率の良い実装方法などご存知の方おられましたら、 お手数ですが、ご教授お願い致します。 【案1】 CString StMinMonth; CString StMaxMonth; StMinMonth.Format( "%d", 1 ); StMaxMonth.Format( "%d", 12 ); CString StMonth; m_xcStMonth.GetWindowText( StMonth ); // コンボボックスの値を取得 char CmpMonth [ MAX_WORD_SIZE + 1 ] = ""; char CmpMinMonth[ MAX_WORD_SIZE + 1 ] = ""; char CmpMaxMonth[ MAX_WORD_SIZE + 1 ] = ""; strcpy_s( CmpMonth, MAX_WORD_SIZE + 1, StMonth ); strcpy_s( CmpMinMonth, MAX_WORD_SIZE + 1, StMinMonth ); strcpy_s( CmpMaxMonth, MAX_WORD_SIZE + 1, StMaxMonth ); int RetMonth1 = strcmp( CmpMonth, CmpMinMonth ); //(1) int RetMonth2 = strcmp( CmpMonth, CmpMaxMonth ); //(2) if( ( RetMonth1 < 0 ) || ( RetMonth2 > 0 ) ) { return false; } return true; 【案2】 CString StMinMonth; CString StMaxMonth; StMinMonth.Format( "%d", 1 ); StMaxMonth.Format( "%d", 12 ); CString StMonth; m_xcStMonth.GetWindowText( StMonth ); // コンボボックスの値を取得 int RetMonth1 = StMonth.Compare( StMinMonth ); //(1) int RetMonth2 = StMonth.Compare( StMaxMonth ); //(2) if( ( RetMonth1 < 0 ) || ( RetMonth2 > 0 ) ) { return false; } return true;

  • コンボボックス 1文字入力できてしまう VBA

    お世話になっております。 Excel2003を使用しております。 コマンドボタンを押したときにコンボボックスをいじられては困るので、 コンボボックスの設定を Me.ComboBox1.Locked = True にしているのですが、 1文字入力できてしまい、 自動的にリストの内部を探してしまいます。 これを防ぐ方法(入力も選択もできないようにする方法)はありませんか? Enable=False にするしかないでしょうか?

  • コンボボックスの変更に応じてテキストボックスの有効を切り替える(ExcelVBA2007)

    お世話になります。 Excel VBA 2007で質問です。 今、  Label1 ComboBox1 TextBox1  Label2 ComboBox2 TextBox2 ・・・  Label100 ComboBox100 TextBox100 のようなフォームがあるとします。 ComboBox1~100は「Any」「is」「is not」のいずれかの値が取れ、初期値はAnyとします。 TextBox の Enabled プロパティの初期値は False とします。 やりたいことは、 ComboBox が「Any」でない場合(is または is not のいずれかの場合)にのみその右隣の TextBox の Enabled プロパティを True にしたいのです。 いま、ComboBox30 を Any から is に切り替えたとします。 すると、TextBox30.Enabled を False から True にしたいのです。 ここで、ComboBox30 を is から is not に切り替えたとします。 TextBox30.Enabled は True のままです。 ここで、ComboBox30 を is not から Any に切り替えたとします。 すると、TextBox30.Enabled を True から False にしたいのです。 ComboBox のイベントハンドラで Sub ComboBox30_Change ()  If ComboBox30.Value = "Any" Then   TextBox30.Enabled = "False"  Else   TextBox30.Enabled = "True"  End If End Sub のように書けばいいことは分かっているのですが、その場合は数字だけ変えたイベントハンドラを100個書かなければなりません。 このイベントハンドラを1個にすることはできるでしょうか。 (コンボボックス100個のうちどれかが変更されたら、変更されたコンボボックスの番号を知りながら呼び出されるハンドラ) 次善の策として、 Sub ComboBox30_Change ()  userSubroutine End Sub のように書くこともできるかと思いますが、この場合、どのコンボボックスが変更されたか(どのイベントハンドラが起動されたか)を知って、userSubroutine に渡さなければなりません。 よろしくお願いします!

  • テキストボックスに文字列を入れる

    開発環境 XP Home Edtion Microsoft Visual C++ 2008 Express Edition Microsoft SQL Server 2003 Express Edition SQL文で1から5までのNoIDを取得してそれをダイアログのテキストボックスIDC_XS1からIDC_XS5の場所に入れようとしています。 int i=1; String^ str; char* dstChar2; LPSTR dstLPSTR2; SqlConnection^ sqlConn = gcnew SqlConnection("Data Source=.\\SQLEXPRESS;AttachDbFilename=C:\\SOUTUKEN\\test.mdf;Integrated Security=True;User Instance=True"); while(i<=5){ sqlConn->Open(); str= "SELECT * FROM Table1 WHERE NoID='"+i+"'"; SqlCommand^ sqlCmd = gcnew SqlCommand(str,sqlConn); SqlDataReader^ exeReader = sqlCmd->ExecuteReader(); while(exeReader->Read()){ str=exeReader["nyuryoku"]->ToString(); dstChar2 = (char*)(void*)Marshal::StringToHGlobalAnsi(str); dstLPSTR2 = (LPCSTR)dstChar2; #define IDC_XS IDC_XS##i        //iの内容をIDC_XSに連結させたいのですがなかなかできないのです。 SetDlgItemText(hWnd,IDC_XS,dstLPSTR2); i++; } sqlConn->Close(); どのようにしたらテキストボックス5つの中にSQL文の結果が入るのでしょうか。何卒よろしくおねがいします。

  • 文字列の扱い方

    初歩的な質問ですみません… str文字列からcという文字を見つけたら添字を返すという関数を作ったのですが、 iにこの関数を代入して、if文の制御式にiを使って比較するまでは正常なのですが、 真文にiを使うと何故か偽文(という言い方でいいのでしょうか…この場合("そんな値はありません。"というところです)が実行されてしまいます。 よろしければご教授お願い致します。 #include <stdio.h> int str_char(const char str[],int c) { int len = strlen(str); int i; for (i = 0;i < len;i++) { if (str[i] == c) return i; } return -1; } int main() { char str[64] = "Fucking Brutal Death Metal"; int ch,i; printf("どの文字を調べますか?"); scanf("%c",&ch); i = str_char(str,ch); if (i >= 0) printf("その文字は%d番目にあります。",str_char(str,ch) + 1); //何故かiだと動かない else printf("そんな値はありません。"); return 0; }

  • 文字列クラスを作りたいと思っています

    文字列クラスを作りたいと思っています。 以下のようなところまでは作れましたが、 エラーがでてしまいます。 どこかおかしいところがあるのでしょうか? *********************************************** #include<stdio.h> #include<string.h> class stt { public: char *str; int len; bool maked; stt::stt() { len=0; str=NULL; maked=false; } stt::~stt() { delete[] str; } stt &operator =(char *c) { if(maked) { delete[] str; maked=false; } len=strlen(c); str=new char[len]; strcpy(str,c); maked=true; return (*this); } virtual operator char*() { return str; } }; int main() { stt s; s="Hello World"; printf(s); getchar(); return 0; } ***********************************************

  • オプションボタン選択でコンボボックス有効

    ExcelVBAでユーザーフォームを作成しているのですが、昨日までうまく動作していたことが、突然動かなくなりました。 オプション1を選択 ↓ コンボボックス1有効  ※他のコンボボックスは無効 ↓ オプション2を選択 ↓ コンボボックス2有効  ※コンボボックス1も含め他のコンボボックスは無効 という感じで動作させたいです。 書いたコードはこんな感じです。 Private Sub OptionButton1_Click () Dim i As Long Dim lastRow As Integer lastRow = Cells(Row.Count, 1).End(xlUp).Row If OptionButton1.Value = True Then OptionButton1.Enabled = True With ComboBox1 If ComboBox1 = "" Then For i = 2 To lastRow .AddItem Worksheets("sheet1").Cells(i, 1).Value Next i End If End With ComboBox1.ListIndex = 0 ComboBox2.Enabled = False ComboBox3.Enabled = False End If End Sub コードの間違いや改善点などありましたら教えて下さい。 よろしくお願いします。

  • コンボボックスの操作

    Javascript勉強中のものです。 皆様、宜しくお願いします。 まず画面内に時間のコンボボックスを4つ もっています。(開始/終了:時/分) こちらで教えて頂きコンボボックスの値をループで簡単に 書くことが出来ましたが、例えば 開始時間が「17」時であったら、「17」時未満(0~16時まで)の 値(時間)がコンボに表示されないようにさせることは可能ですか? また、開始コンボ(時)と終了コンボ(時)が同時刻の場合 終了コンボ(分)は、開始コンボ(分)より以前を表示させない ような制御は可能でしょうか?? コンボの値を変える度にコントロールしたいです。 ややこしい話ですが、どなたか教えて頂けませんか? //時間のコンボ Function Cmbhh1(){  var arrCmb = new Array();  i = 0;  for(i = 1; i<25; i++) { arrCmb[i] = i; } return arrCmb; } //分のコンボ(15分単位) Function Cmbmm1(){  var arrCmb = new Array();   arrCmb[0] = 0;   i = 0;   for(i = 0; i<56; i++) {    arrCmb[i] = i;    i = i + 4;    } return arrCmb; }

  • ACCESS VBA で複数項目検索にテキストボックスとコンボボックス

    ACCESS VBA で複数項目検索にテキストボックスとコンボボックスを使用したい txtPC番号というテキストボックス、 com所属部門というコンボボックス、 txt使用者というテキストボックスの どれかひとつの条件が入力されたときに 該当するフォームのレコードを抽出できるようにしたいのですが、 コンボボックスで選択した場合のみうまく抽出できません。 コードのどの部分に誤りがあるのでしょうか? ご指摘願えませんでしょうか? よろしくお願いいたします。 Private Sub cmd01_Click() Me.FilterOn = False If Me!txtPC番号 <> "" Then Me.Filter = "[PC番号]like '*" & Me!txtPC番号 & "*'" ElseIf Me!com所属部門 <> "" Then DoCmd.Requery "com所属部門" ElseIf Me!txt使用者 <> "" Then Me.Filter = "[使用者]like '*" & Me!txt使用者 & "*'" End If Me.FilterOn = True End Sub