プログラム内容の要約

このQ&Aのポイント
  • このプログラムは、リストボックスのポインタを取得し、リストボックスのアイテムを全て消去します。
  • また、ファイルを読み込んでリストボックスへ割り当てる機能も持っています。
  • 具体的な処理の流れとしては、ファイルを選択し、ファイルの内容を1文字ずつ読み込みます。読み込んだ文字が数字かドット(小数点)の場合は、数字として扱い、それ以外の場合はアルファベットとして扱います。読み込んだ文字をデータとして追加していく過程で、データが数字かアルファベットかでリストボックスに追加する先が異なります。最後に読み込んだ文字列をリストボックスに追加し、ファイルを閉じます。
回答を見る
  • ベストアンサー

プログラム内容

{ // リストボックスのポインタを取得する CListBox* listbox1 = (CListBox*)GetDlgItem(IDC_LIST1); CListBox* listbox2 = (CListBox*)GetDlgItem(IDC_LIST2); // リストボックスのアイテムを全て消去する listbox1->ResetContent(); listbox2->ResetContent(); // ファイルを読み込んでリストボックスへ割り当てる CFileDialog dlg(TRUE); if (dlg.DoModal() == IDOK) { CHAR buf = '\0'; BOOL isnum = FALSE; CString data = ""; CFile file(dlg.GetPathName(), CFile::modeRead); while (file.Read(&buf, 1) != FALSE) { // 0~9かドット(小数点?)の場合は数字として扱い、それ以外はアルファベットとする if (isdigit((int)buf) != 0 || buf == '.') { if (data.GetLength() == 0) { data += buf; isnum = TRUE; } else if (isnum == FALSE) { istbox2->AddString(data); data = buf; isnum = TRUE; } else { data += buf; } } if (isalpha((int)buf) != 0) { if (data.GetLength() == 0) { data += buf; isnum = FALSE; } else if (isnum == TRUE) { listbox1->AddString(data); data = buf; isnum = FALSE; } else { data += buf; } } } // 最後に読み込んだ文字列をリストボックスへ追加する if (data.GetLength() != 0) { if (isnum == TRUE) { listbox1->AddString(data); } else { listbox2->AddString(data); } } // ファイルを閉じる file.Close(); } } のプログラムなんですが大筋はコメントで書いてある通りなんですが きっちり理解したい為、一行一行のプログラムが何を示すのか 教えてください。最初のポインタ取得とリストボックス内削除と 最後のファイル閉じるは明白なので省いてもらって結構です

  • zaqwe
  • お礼率15% (19/123)

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

  • ベストアンサー
  • t4t
  • ベストアンサー率55% (47/84)
回答No.1

こんなもんでいかがと思いますが・・・ { // リストボックスのポインタを取得する CListBox* listbox1 = (CListBox*)GetDlgItem(IDC_LIST1); CListBox* listbox2 = (CListBox*)GetDlgItem(IDC_LIST2); // リストボックスのアイテムを全て消去する listbox1->ResetContent(); listbox2->ResetContent(); // ファイルを読み込んでリストボックスへ割り当てる CFileDialog dlg(TRUE);//「ファイルを開く」ダイアログを表示 if (dlg.DoModal() == IDOK)//「ファイルを開く」ダイアログでOK選択」 { CHAR buf = '\0'; BOOL isnum = FALSE; CString data = ""; CFile file(dlg.GetPathName(), CFile::modeRead);//「ファイルを開く」で選択されたファイルをオープン while (file.Read(&buf, 1) != FALSE) //ファイルを1文字ずつ読み込み、全部読むまで繰り返す { // 0~9かドット(小数点?)の場合は数字として扱い、それ以外はアルファベットとする if (isdigit((int)buf) != 0 || buf == '.') // 今読んだ1文字が0~9または.か { if (data.GetLength() == 0) { // ファイルの最初の文字が0~9かドットの場合の処理 data += buf; // dataに今読んだ1文字を追加 isnum = TRUE; // いま数字を扱っている } else if (isnum == FALSE) { // さっきまで読んでた文字が数字扱いじゃなかった // (つまりさっきまではアルファベットを読んでいて、今数字を読み始めた) listbox2->AddString(data); // さっきまで読んでいた文字の列(data)つまりアルファベットの文字列をlistbox2に追加する data = buf; // dataを一回消して、今読んだ1文字(数字)をdataに設定 isnum = TRUE; // いま数字を扱っている(アルファベットから数字に切り替わった) } else // さっきまで読んでた文字も数字で今読んだ文字も数字だった { // 今読んだ1文字をdataの後ろに追加する。(数字の文字列がdataに作られる) data += buf; } } if (isalpha((int)buf) != 0) // 今読んだ1文字がアルファベットか { if (data.GetLength() == 0) // ファイルの最初の文字がアルファベットの場合の処理 { data += buf;// dataに1文字を追加 isnum = FALSE;// いま数字を扱っていない } else if (isnum == TRUE) { // さっきまで読んでた文字が数字扱いだった // (つまりさっきまでは数字を読んでいて、今アルファベットを読み始めた) listbox1->AddString(data);// さっきまで読んでいた文字の列(data)つまり数字の文字列をlistbox1に追加する data = buf;// dataを一回消して、今読んだ1文字(アルファベット)をdataに設定 isnum = FALSE;//いま数字を扱っていない(数字からアルファベットに切り替わった) } else // さっきまで読んでた文字もアルファベットで今読んだ文字もアルファベットだった { // 今読んだ1文字をdataの後ろに追加する。(アルファベットの文字列がdataに作られる) data += buf; } } } // 最後に読み込んだ文字列をリストボックスへ追加する if (data.GetLength() != 0) { if (isnum == TRUE) // dataの中が数字なら { listbox1->AddString(data); // listbox1に追加 } else // アルファベットなら { listbox2->AddString(data); // listbox2に追加 } } // ファイルを閉じる file.Close(); } }

zaqwe
質問者

お礼

ありがとうございました

zaqwe
質問者

補足

CHAR buf = '\0'; BOOL isnum = FALSE; 上記にあるこの2行はどういう意味なんでしょうか?

その他の回答 (2)

  • t4t
  • ベストアンサー率55% (47/84)
回答No.3

>CHAR buf = '\0'; >BOOL isnum = FALSE; >上記にあるこの2行はどういう意味なんでしょうか? 自明だと思ってコメントしませんでしたが、 isnumは数字かどうかを判断するためのフラグで、これも変数を宣言しただけでは内部が不定値(どんな値が入っているかわからない)なのでFALSEで初期化しているのでしょう。 ifなどでその変数を判断する前に、はっきりと値を入れるのがプログラミングの常識的なマナーとされていますので、そのマナーに従っての初期化でしょう。 なお、このプログラムにおいては、TRUEで初期化しても正しい結果が得られると思います。 bufはファイルを1文字ずつ読むための変数で、変数を宣言しただけでは内部が不定値(どんな値が入っているかわからない)なので、'\0'(ヌル文字)で初期化しているのでしょう。while(file.Read...でファイルを読んだ内容が設定されるので、マナー的にも特にヌルで初期化する必要は実際にはありません。精神衛生的(初期化しないとなんとなく気分悪いとか)なものでしょう。 なお、バグを削減するために"変数は宣言と同時に必ず初期化する"というルールを課しているプログラミングスタイルもありますので、そのスタイルに沿ったものかもしれませんね。

回答No.2
zaqwe
質問者

お礼

連続して聞かれると嫌だと思う人もいるからです。 2つの掲示板を行き来してはいけないという規約もないでしょうし 嫌味を言われる筋合いもございません。

関連するQ&A

  • CListBoxでAddString等をすぐに反映

    WindowsのVisualC++です。 ダイアログベースで作っています。 この中でたとえば、 OnButtonXXX() というボタンを押したときに動くサブルーチンがあったとして、 OnButtonXXX() {   m_listbox.ResetContents();   m_listbox.AddString( "begin" );   m_listbox.AddString( "working..." ); ポイントA   長くかかる処理   m_listBox.AddString( "end処理");   m_listbox.ResetContents();   m_listbox.AddString( 結果ずらっと ) } みたいなルーチンを作ると、残念ながら、長くかかる処理が終ってからまとめてリストボックスに反映されて、 処理中に begin, working... 等をリストボックス内に表示させてユーザーに知らせるということが出来ません。 上記ポイントAに、何か、CWndとか上位のクラスの何かを書いて反映させるとかできないでしょうか。 あるいは、CListBoxのクラスメンバに描画関数とかありますか。 ちなみに、ポイントAに Invalidate(false); を置いてもダメでした。

  • コンボボックスにリストを表示させるには?

    VC++6.0でコンボボックスにリストを表示させようと思っているのですが プロパティのところのデータに追加しても表示されません ほかに設定するところはあるのでしょうか? もちろんコンボボックスは生きています。 他のhpをみて CComboBox* p = (CComboBox*)GetDlgItem(IDC_COMBO1); p->ResetContent(); p->AddString("項目2"); p->AddString("項目1"); p->AddString("項目4"); p->AddString("項目3"); も試してみたのですがうまくいきません。 よろしくお願いいたします。

  • 【エクセル】オプションボタンにセルの値を反映させるには

    エクセルマクロ初心者です。教えてください。 シート2 の あるセルの値が A のとき シート1上の オプションボタン1がtrueになる。 シート2 の あるセルの値が A以外のとき シート1上の オプションボタン1がfalseになる。 (オプションボタン1はフォームコントロールのオプションボタンです。) という結果になるマクロの登録方法を模索していますがうまくいきません。 実際には、シート1は入力シートで、ボタンクリックで別の蓄積シートに転記(オプションボタンのほかコンボボックスなどの内容を転記します)。シート1上のリストボックスに蓄積シートの内容を表示し、選択するとその内容を呼び出すようにしたいのです。 コンボボックスやテキストボックスに呼び出すところまではなんとか本を見たりしてできたのですが、オプションボタンに呼び出せません。 なんとかお知恵をお借りしたいです。 よろしくおねがいします。 *下記のようにやってみました。 Private Sub commandbutton3_click() Dim n As Integer n = ListBox1.ListIndex If n = -1 Then MsgBox "選択してください" Else ComboBox2.Value = ListBox1.List(n, 0) ComboBox3.Value = ListBox1.List(n, 3) ComboBox4.Value = ListBox1.List(n, 4) ComboBox5.Value = ListBox1.List(n, 8) ComboBox6.Value = ListBox1.List(n, 9) ComboBox7.Value = ListBox1.List(n, 1) ComboBox8.Value = ListBox1.List(n, 2) TextBox3.Value = ListBox1.List(n, 10) End if ***********ここからがうまくいきません******** If Worksheets("入力シート").ListBox1.List(n, 6).Value = "A" Then OptionButton1.Value = True Else OptionButton("A").Value = False End If End Sub

  • TextをEnterKeyで選んだ後にLISTBOXを非表示

    OSはWin XP home EXCEL2002を使用しています。 ActivecellにリストボックスのデータをEnterKeyで入れた後にリストボックスの表示をFalseにしたいと思っています。以下のようにすると必ずEXCELが落ちてしまいます。 Private Sub ListBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger) If KeyAscii = vbKeyReturn Then ActiveCell.Value = ListBox1.Text ListBox1.Visible = False End If End Sub 何がいけないのかよく分かりません。悪い部分の解説もできればお願いしたいと思います。よろしくお願いします。

  • リストボックスから複数行を選択し、その複数のデータをセルに入力したい

    Excel2003でマクロをつくっています。シートのB列を右クリックすると、リストボックスが表示され 任意1行を選択するとシートのB列、C列、D列のセルにデーターが入力されます。 Private Sub ListBox2_Click() With ListBox2 If .ListIndex = -1 Then MsgBox "項目を選択してくだい" Else ’シートが保護されていたら保護を解除 If ActiveSheet.ProtectContents = True Then ActiveSheet.Unprotect End If ActiveCell.Value = ListBox2.List(ListBox2.ListIndex, 0) ActiveCell.Offset(0, 1).Value = ListBox2.List(ListBox2.ListIndex, 1) ActiveCell.Offset(0, 2).Value = ListBox2.List(ListBox2.ListIndex, 2) ActiveSheet.Protect End If End With Unload UserForm3 End Sub このリストボックスから複数の行を選択し、シートのB列、C列、D列のセルにデーターを入力したいのですが、Multiselectプロパティを変更しても、一行のみしか入力できません。 上のコードをどうかえたらよろしいでしょうか。

  • ExcelVBA リストボックスの複数選択処理がうまくいきません

    こんばんは、助けてください。 EXCEL2007です。 ユーザーフォームにリストボックス(Listbox1)を複数選択可能で作成。 リストボックス各行の4列目には「A」か「B」のいずれかが入っており、選択した行の4列目が「A」ならば「B」を、 「B」ならば「A」をCommandButton1押下でセルに反映させたいのですが、うまくいきません。 [反映先のセル] ・リストボックス1行目⇒セルC4(列番号3) ・リストボックス2行目⇒セルG4(列番号7) ・リストボックス3行目⇒セルK4(列番号11) ・リストボックス4行目⇒セルO4(列番号15) ・リストボックス5行目⇒セルS4(列番号19) ・以降同規則でつづく [コード] 01 Private Sub CommandButton1_Click() 02   Dim ListRow As Integer 03   Dim Retsu As Integer 04 05   For ListRow = 0 To Listbox1.ListCount - 1 06     If Listbox1.Selected(ListRow) Then 07       Retsu = (ListRow + 1) * 3 + ListRow 08       If Listbox1.List(ListRow, 3) = "A" Then 09         Cells(4, Retsu).Value = "B" 10       Else 11         Cells(4, Retsu).Value = "A" 12       End If 13    End If 14  Next ListRow 15 End Sub [現象] 1.単一選択時は、OK。 2.複数選択時は、選択した行のうち一番はじめの行のみOK。 3.試しに、EndSub直前でListbox1.Selected(各ListRow)を検証すると、すべてFalseになってしまっている。 4.IF文(07~12行目)を削除した上で、EndSub直前でListbox1.Selected(各ListRow)を検証すると、True/Falseは意図通りになっている。 IF文(07~12行目)が悪さをしているのでしょうか? うまいやり方をご教授いただければ、幸いです。m(_ _)m

  • リストボックスで選択した一行を一度にセルに入力したい

    Xcel2003でマクロ作成中です。以下のコードで、リストボックスで一行を選択しました。この選択した一行のデータのうち2個のデータをC列とD列に入力することができました。が、E列にもデータを入力したいのです。が色いろやってみましたができません。 Private Sub ListBox2_Click() With ListBox2 If .ListIndex = -1 Then MsgBox "項目を選択してくだい" Else ActiveCell.Value = ListBox2.list(ListBox2.ListIndex, 0) ActiveCell.Offset(0, 1).Value = ListBox2.list(ListBox2.ListIndex, 1) End If End With Unload UserForm3 End Sub 上のコードにどう追加記入したらよろしいでしょうか?

  • VB6.0 リストボックス

    VB6.0で3つのリストボックスに関連性を持たせたいと思っています。 Private Sub lstBox_Click() Dim intLstIndex As Integer intLstIndex = lstA.ListIndex If (lstA.Selected(intLstIndex)) Then lstB.Selected(intLstIndex) = True lstC.Selected(intLstIndex) = True Else lstB.Selected(intLstIndex) = False lstC.Selected(intLstIndex) = False End If End Sub 以上のように、どれか一つのリストボックスがクリックされたら他のリストボックスの同じ行がtrueになるようにしています。 しかしこれでは件数が増えた場合、選択された行が揃わなくなる場合があり非常に見栄えが悪くなります。 リストボックスでなくともかまわないのですが、このように三つの項目に関連性をもたせることはできませんでしょうか。

  • リストボックスの1行目を選択状態にする

    リストボックス 何も選択していないのなら、1行目を選択状態にする というようにするにはどうすればいいでしょうか? 今は無理やり Sub test() If IsNull(Sheets("Sheet2").ListBox1.Value) = True Then Sheets("Sheet2").ListBox1.Value = "a" End If End Sub としていますが、 「リストボックスの1行目を選択状態にする」 にはどうすればいいですか? リストボックスがどの業も選択してない時に、 画像のようにしたいです。

  • 文字列の比較に関する質問

    文字列をif文で比較したいのですが、まず下記の例だと char *a a="a"; if(a=="a"){ printf("等しい"); }else{ printf("等しくない"); } 文字列は等しくなるのですが下記の例ではなりません 何故なのでしょうか。 read(s_sock,&buf,sizeof(buf)) if(a=="GET"){ printf("TRUE") }else{ printf("FALSE"); }

専門家に質問してみよう