質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MFC

MFC (Microsoft Fouondation Class)とは、MicrosoftがVC++用に開発したWindows用アプリケーションのフレームワークです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

5142閲覧

C++ ファイル入出力+ListControlについて

NaokiPooh

総合スコア21

MFC

MFC (Microsoft Fouondation Class)とは、MicrosoftがVC++用に開発したWindows用アプリケーションのフレームワークです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2016/11/17 01:56

お世話になっております。
C++を学習中の学生です。
前回同じような質問をさせていただきましたが、解決することができず再度質問させていただくことをお許しください。

現在ダイヤログベースの住所録アプリケーションを作成中です。
以下画面
イメージ説明
左側の各情報を入力し送信押下後ファイル入出力をさせリストに表示させております。
以下テキストファイル中身
イメージ説明
テキストファイルの中身を1行ずつ読み込んでリストに表示させています。

そこで実装したい機能として
リスト内で選択をした項目の更新・削除を行いたい。
更新をされた場合は更新情報を取得し、現在のテキストファイルを削除(または上書き)し新しいテキストファイルを作成し、リストに表示させる。
具体例)
[3 男性 鈴木一郎 46 7654321 埼玉県春日部市]を
[3 男性 鈴木一郎 46 1234567 東京都葛飾区]に変更した時
イメージ説明
のようにしたい。
分からない事としてリストのデータを再取得したい場合をどうしたらよいか
上記でいう1~からの情報をどのように処理されば取得できるかということです。

ご教授いただければ幸いです。
以上、よろしくお願いいたします。

C++

1 2//------------------------------------------------------------------------------ 3// 送信ボタン押下処理 4//------------------------------------------------------------------------------ 5void CZyuSyoDlg::OnBnClickedGo() 6{ 7 struct Queue *head; 8 head = QueCut(); 9 10 //------------// 11 //名前部の取得// 12 //------------// 13 CString strName; 14 ((CEdit*)GetDlgItem(IDC_NAME_I))->GetWindowText( strName ); 15 //CString → charへの変換 16 strcpy_s( head->data.name, strName ); 17 18 //------------// 19 //住所部の取得// 20 //------------// 21 CString strHome; 22 ((CEdit*)GetDlgItem(IDC_HOME_I))->GetWindowText( strHome ); 23 strcpy_s( head->data.home, strHome ); 24 25 //------------// 26 //年齢部の所得// 27 //------------// 28 CString strTosi; 29 ((CEdit*)GetDlgItem(IDC_TOSI_I))->GetWindowText( strTosi ); 30 strcpy_s( head->data.tosi, strTosi ); 31 32 //------------// 33 //〒(前)の取得// 34 //------------// 35 CString strYu1; 36 ((CEdit*)GetDlgItem(IDC_YUBIN_1))->GetWindowText( strYu1 ); 37 strcpy_s( head->data.yu1, strYu1 ); 38 39 //------------// 40 //Noの所得 // 41 //------------// 42 CString strNo; 43 m_Combo.GetLBText(m_Combo.GetCurSel(),strNo); 44 45 //テキスト用テキストファイル読み込み 46 if( strNo != "" ) 47 { 48 CString strNoData; 49 CStdioFile ZyuSyoFile3("NoData.txt", CFile::modeCreate | CFile::modeNoTruncate | 50 CFile::modeRead | CFile::typeText); 51 //1行ずつ読み込ませる 52 BOOL strRead2; 53 while( 1 ) 54 { 55 strRead2 = ZyuSyoFile3.ReadString( strNoData ); 56 if( strRead2 == FALSE ) 57 { 58 break; 59 } 60 //読み込んだ値と取得した値を比べる 61 m_No = strNoData; 62 if( m_No == strNo ) 63 { 64 MessageBox("Noが重複しています!","†警告†",MB_OK | MB_ICONSTOP); 65 return; 66 } 67 68 } 69 } 70 71 strcpy_s( head->data.no, strNo ); 72 73 //----------------// 74 //性別の取得(男性)// 75 //----------------// 76 CString strType; 77 if( ( (CButton*)GetDlgItem(IDC_RADIO_B) )->GetCheck() == BST_CHECKED ) 78 { 79 strType = ("男性"); 80 strcpy_s( head->data.type, strType ); 81 } 82 83 //----------------// 84 //性別の判定(女性)// 85 //----------------// 86 if( ( (CButton*)GetDlgItem(IDC_RADIO_G) )->GetCheck() == BST_CHECKED ) 87 { 88 strType = ("女性"); 89 strcpy_s( head->data.type, strType ); 90 } 91 92 93 //----------------// 94 //リストへ追加 // 95 //----------------// 96 // リストコントロール 行の追加 97 int count = m_List.GetItemCount(); 98 m_List.InsertItem(count, strNo); //No行を追加 99 m_List.SetItem(count, 1, LVIF_TEXT, strType, 0, 0, 0, 0); //性別行を追加 100 m_List.SetItem(count, 2, LVIF_TEXT, strName, 0, 0, 0, 0); //名前列を追加 101 m_List.SetItem(count, 3, LVIF_TEXT, strTosi, 0, 0, 0, 0); //年齢行を追加 102 m_List.SetItem(count, 4, LVIF_TEXT, strYu1, 0, 0, 0, 0); //郵便番号行を追加; 103 m_List.SetItem(count, 5, LVIF_TEXT, strHome, 0, 0, 0, 0); //住所行 104 105 //----------------// 106 //ファイル入出力 // 107 //----------------// 108 CStdioFile ZyuSyoFile; 109 //テキストファイルを開く 110 ZyuSyoFile.Open("ZyuSyoData.txt",CFile::modeReadWrite | 111 CFile::shareDenyNone | CFile::modeCreate | CFile::modeNoTruncate); 112 113 //テキストファイルの最後に追加していく 114 ZyuSyoFile.SeekToEnd(); 115 116 //各要素をテキストファイルに 117 ZyuSyoFile.WriteString( strNo + "\n" ); 118 ZyuSyoFile.WriteString( strType + "\n" ); 119 ZyuSyoFile.WriteString( strName + "\n" ); 120 ZyuSyoFile.WriteString( strTosi + "\n" ); 121 ZyuSyoFile.WriteString( strYu1 + "\n" ); 122 ZyuSyoFile.WriteString( strHome + "\n" ); 123 124 //テキストファイルを閉じる 125 ZyuSyoFile.Close(); 126 127 //No用テキストファイル作成 128 CStdioFile ZyuSyoFile2; 129 ZyuSyoFile2.Open("NoData.txt",CFile::modeReadWrite | 130 CFile::shareDenyNone | CFile::modeCreate | CFile::modeNoTruncate); 131 ZyuSyoFile2.SeekToEnd(); 132 ZyuSyoFile2.WriteString( strNo + "\n" ); 133 ZyuSyoFile2.Close(); 134 135 QueData(head); 136} 137 138//------------------------------------------------------------------------------ 139// リスト処理 140//------------------------------------------------------------------------------ 141void CZyuSyoDlg::OnLvnItemchangedList1(NMHDR *pNMHDR, LRESULT *pResult) 142{ 143 LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR); 144 // TODO: ここにコントロール通知ハンドラー コードを追加します。 145 146 CEdit* pEdit = (CEdit *)GetDlgItem( IDC_NAME_I ); 147 CEdit* pEdit1 = (CEdit *)GetDlgItem( IDC_HOME_I ); 148 CEdit* pEdit2 = (CEdit *)GetDlgItem( IDC_TOSI_I ); 149 CEdit* pEdit3 = (CEdit *)GetDlgItem( IDC_YUBIN_1 ); 150 151 152 // 選択されているアイテムの0列目のテキストを表示. 153 int idx = -1; // インデックスidxを-1で初期化. 154 TCHAR strName[256]; 155 TCHAR strHome[256]; 156 TCHAR strTosi[256]; 157 TCHAR strYu1[256]; 158 159 160 CListCtrl *pListCtrl1 = (CListCtrl *)GetDlgItem(IDC_LIST1); 161 while( ( idx = pListCtrl1->GetNextItem(idx, LVNI_SELECTED ) ) != -1 ) 162 { 163 pListCtrl1->GetItemText(idx, 2, strName, 256); 164 pListCtrl1->GetItemText(idx, 3, strTosi, 256); 165 pListCtrl1->GetItemText(idx, 4, strYu1, 256); 166 pListCtrl1->GetItemText(idx, 5, strHome, 256); 167 168 // pListCtrl1->GetItemTextでidx行0列のテキストを取得し,それぞれに格納. 169 pEdit ->SetWindowText(strName); 170 pEdit1 ->SetWindowText(strHome); 171 pEdit2 ->SetWindowText(strTosi); 172 pEdit3 ->SetWindowText(strYu1); 173 } 174 175 176 *pResult = 0; 177} 178 179 180//------------------------------------------------------------------------------ 181// 更新ボタン 182//------------------------------------------------------------------------------ 183void CZyuSyoDlg::OnBnClickedHenB() 184{ 185 POSITION pos; 186 while( 1 ) 187 { 188 pos = m_List.GetFirstSelectedItemPosition(); 189 if(!pos) 190 { 191 break; 192 } 193 int nItem = m_List.GetNextSelectedItem(pos); 194 //各情報の取得 195 CString strName; 196 ((CEdit*)GetDlgItem(IDC_NAME_I))->GetWindowText( strName ); 197 CString strHome; 198 ((CEdit*)GetDlgItem(IDC_HOME_I))->GetWindowText( strHome ); 199 CString strTosi; 200 ((CEdit*)GetDlgItem(IDC_TOSI_I))->GetWindowText( strTosi ); 201 CString strYu1; 202 ((CEdit*)GetDlgItem(IDC_YUBIN_1))->GetWindowText( strYu1 ); 203 204 //変更された情報を行へ追加 205 m_List.SetItem(nItem, 2, LVIF_TEXT, strName, 0, 0, 0, 0); 206 m_List.SetItem(nItem, 3, LVIF_TEXT, strTosi, 0, 0, 0, 0); 207 m_List.SetItem(nItem, 4, LVIF_TEXT, strYu1, 0, 0, 0, 0); 208 m_List.SetItem(nItem, 5, LVIF_TEXT, strHome, 0, 0, 0, 0); 209 210 //ファイル入出力 211 CStdioFile ZyuSyoFile; 212 //テキストファイルを開く 213 ZyuSyoFile.Open("ZyuSyoData.txt",CFile::modeReadWrite | 214 CFile::shareDenyNone | CFile::modeCreate ); 215 //テキストファイルの最後に追加していく 216 ZyuSyoFile.SeekToEnd(); 217 218 break; 219 } 220} 221 222 223//------------------------------------------------------------------------------ 224// ロードボタン 225//------------------------------------------------------------------------------ 226void CZyuSyoDlg::OnBnClickedRoad() 227{ 228 //------------------// 229 //ファイル入出力 // 230 //------------------// 231 struct Queue *head; 232 head = QueCut(); 233 234 //ボタン押下後ListControlをクリア 235 m_List.DeleteAllItems(); 236 ASSERT( m_List,GetItemCount() == 0 ); 237 238 //各要素の変数 239 CString strNo; 240 CString strType; 241 CString strName; 242 CString strTosi; 243 CString strYu1; 244// CString strYu2; 245 CString strHome; 246 247 //テキストファイル読み込み 248 CStdioFile ZyuSyoFile("ZyuSyoData.txt",CFile::modeCreate | CFile::modeNoTruncate | 249 CFile::modeRead | CFile::typeText); 250 CString ReadFile = ""; 251 252 //一行づつ読み込む 253 BOOL strRede; 254 while( 1 ) 255 { 256 //No読み込み 257 strRede = ZyuSyoFile.ReadString( strNo ); 258 strcpy_s( head->data.no, strNo ); 259 if( strRede == FALSE ) 260 { 261 break; 262 } 263 //性別読み込み 264 strRede = ZyuSyoFile.ReadString( strType ); 265 strcpy_s( head->data.type, strType ); 266 if( strRede == FALSE ) 267 { 268 break; 269 } 270 //名前読み込み 271 strRede = ZyuSyoFile.ReadString( strName ); 272 strcpy_s( head->data.name, strName ); 273 if( strRede == FALSE ) 274 { 275 break; 276 } 277 //年齢読み込み 278 strRede = ZyuSyoFile.ReadString( strTosi ); 279 strcpy_s( head->data.tosi, strTosi ); 280 if( strRede == FALSE ) 281 { 282 break; 283 } 284 //郵便番号(前)読み込み 285 strRede = ZyuSyoFile.ReadString( strYu1 ); 286 strcpy_s( head->data.tosi, strYu1 ); 287 if( strRede == FALSE ) 288 { 289 break; 290 } 291 //住所読み込み 292 strRede = ZyuSyoFile.ReadString( strHome ); 293 strcpy_s( head->data.home, strHome ); 294 if( strRede == FALSE ) 295 { 296 break; 297 } 298 299 //読み込んだ情報を行に追加 300 int count = m_List.GetItemCount(); 301 m_List.InsertItem(count, strNo); //No行を追加 302 m_List.SetItem( count, 1, LVIF_TEXT, strType, 0, 0, 0, 0 ); //性別行を追加 303 m_List.SetItem( count, 2, LVIF_TEXT, strName, 0, 0, 0, 0 ); //名前列を追加 304 m_List.SetItem( count, 3, LVIF_TEXT, strTosi, 0, 0, 0, 0 ); //年齢行を追加 305 m_List.SetItem( count, 4, LVIF_TEXT, strYu1, 0, 0, 0, 0); //郵便番号行を追加 306 m_List.SetItem( count, 5, LVIF_TEXT, strHome, 0, 0, 0, 0 ); //住所行を追加 307 308 309 //テキスト用テキストファイル読み込み 310 CString strNoData; 311 CStdioFile ZyuSyoFile2("NoData.txt", CFile::modeCreate | CFile::modeNoTruncate | 312 CFile::modeRead | CFile::typeText); 313 BOOL strRead2; 314 while( 1 ) 315 { 316 strRead2 = ZyuSyoFile2.ReadString( strNoData ); 317 if( strRead2 == FALSE ) 318 { 319 break; 320 } 321 m_No = strNoData; 322 } 323 324 325 QueData(head); 326 327 } 328 329} 330

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

リストにパラメータのセット/更新ができるならば、取得して保存するのは簡単だと思いますが
Setがあるのですから、対のGetも存在します

コードを載せますが、すごく省略して書いてあるので適宜直してください
手順は、
リストに全部何行あるかを取得して、
それぞれの行から列のデータを取得して
ファイルに書き出す
これだけです

C++

1 2 //全行数を取得 3 int all_data = GetItemCount(); 4 5 CString strNo =""; 6 CString strName =""; 7 CString strPostNo =""; 8 CString strAddress =""; 9 CString strAge =""; 10 int subItemCnt = 0; 11 //スケジュール内容の取得 12 for(int loop = 0;loop < all_data;++loop) 13 { 14 //No 15 strNo = GetItemText(loop,0); 16 //Name 17 strName = GetItemText(loop,1); 18 19 省略 20 21 //ファイル書き込み処理 22 } 23

投稿2016/11/17 02:29

ardin

総合スコア546

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

NaokiPooh

2016/11/17 04:29 編集

回答ありがとうございます! 上記を参考にソースを修正してみました。 //全行数を取得 int all_data = m_List.GetItemCount(); CString strNo = ""; CString strName = ""; CString strType = ""; CString strTosi = ""; CString strYu1 = ""; CString strHome = ""; int subItemCnt = 0; //内容の取得 for(int loop =0;loop<all_data; loop++) { //No strNo = m_List.GetItemText(loop,0); //性別 strType = m_List.GetItemText(loop,1); //名前 strName = m_List.GetItemText(loop,2); //年齢 strTosi = m_List.GetItemText(loop,3); //郵便番号 strYu1 = m_List.GetItemText(loop,4); //住所 strHome = m_List.GetItemText(loop,5); //ファイル入出力 CStdioFile ZyuSyoFile; //テキストファイルを開く ZyuSyoFile.Open("ZyuSyoData.txt",CFile::modeReadWrite | CFile::shareDenyNone | CFile::modeCreate ); //テキストファイルの最後に追加していく ZyuSyoFile.SeekToEnd(); //テキストファイルに追加していく ZyuSyoFile.WriteString( strNo + "\n" ); ZyuSyoFile.WriteString( strType + "\n" ); ZyuSyoFile.WriteString( strName + "\n" ); ZyuSyoFile.WriteString( strTosi + "\n" ); ZyuSyoFile.WriteString( strYu1 + "\n" ); ZyuSyoFile.WriteString( strHome + "\n" ); ZyuSyoFile.Close(); } これで実行をかけるとテキストファイルの中身が 3 男性 鈴木一郎 46 1234567 東京都葛飾区 などと更新する箇所しか保存されないのですが、どう修正をかければよろしいでしょうかorz
episteme

2016/11/17 05:05

1. ファイルを開ける 2. "i番目をファイルに書く"を繰り返す(i=0,1,2..) 3. ファイルを閉じる
ardin

2016/11/17 05:21

---c++ ZyuSyoFile.Open("ZyuSyoData.txt",CFile::modeReadWrite | CFile::shareDenyNone | CFile::modeCreate ); --- に問題があります modeCreateは確か現在のファイルがあっても破棄してしまうはずです。 つまり常に作り直し。Openのオプション(というか引数)を見直してみましょう 今回テスト(?)した状況は3番目(3行)までしかリストがなかったのでは?
episteme

2016/11/17 05:32 編集

それもそうだけど、なんで1-record書くたんびにいちいち開けて閉じるんだ?
ardin

2016/11/17 05:35

あとちょっとしたおせっかい(?) 全行数が分かるので、配列を動的に確保して(またはvectorで) リストのアイテムをそこに入れた後、ファイルに書き込みをしてもいいと思います。 開く閉じるを繰り返していると実行速度が遅くなります。 リスト行数が少ない間は気になりませんけれども。
ardin

2016/11/17 05:40

あ、epistemeさんの指摘している方法が一番楽だorz なんで遠回りの指摘したんだろ
NaokiPooh

2016/11/18 01:07

ZyuSyoFile.Open("ZyuSyoData.txt",CFile::modeReadWrite | CFile::shareDenyNone | CFile::modeCreate | CFile::modeNoTruncate ); としたところ、ファイルの中身に更新前の情報が残ってしまうので、更新後のみの情報をファイルに送るにはどのように修正をかければよろしいでしょうか。
episteme

2016/11/18 01:20

頼むからマニュアル読んで/読めるようになって。 CFile::modeNoTruncate を指定したら以前のが残るって以前にも指摘されなかったっけ?
NaokiPooh

2016/11/18 01:25

CFile::modeCreate にすると最後の行のみしかファイルに送れず、CFile::modeCreate | CFile::modeNoTruncate にすると更新前+更新後がファイルに送られてしまうので、他にやり方はあるのでしょうか。
episteme

2016/11/18 01:32

1. ファイルを開ける(modeWrite|shareDenyWrite) 2. "i番目をファイルに書く"を繰り返す(i=0,1,2..) 3. ファイルを閉じる ※ loop内でファイルをOpen/Closeしない!
guest

0

"テキストファイルの中身を1行ずつ読み込んでリストに表示させ"るのはできてんですよね。

であれば、"リストのデータを再取得したい"なら、
一旦リスト・コントロールの全行を削除しカラッポにしたのち
"テキストファイルの中身を1行ずつ読み込んでリストに表示させ"ればいいじゃん。

投稿2016/11/17 02:09

episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

NaokiPooh

2016/11/17 02:21

いつも回答ありがとうございます! お聞きしたかったのは ”更新押下後、更新情報を含めたリストを再取得(上記の例だと1~東京都葛飾区まで)し、それをテキストファイルに送る方法”です。 上記の2番目のようなテキストファイルにする方法が不明点です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問