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

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

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

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

C++

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

Q&A

解決済

3回答

4688閲覧

ファイル読み込み方法

NaokiPooh

総合スコア21

MFC

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

C++

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

0グッド

0クリップ

投稿2016/11/07 05:26

編集2016/11/07 05:30

お世話になっております。
C++を学習中の学生です。
現在下記のような住所録アプリケーションを作成中です。
イメージ説明
写真右下にある読み込みボタンを押下し
イメージ説明
上記のテキストファイルの中身をリストコントロールに読み込ませたいのですが、どう記述すればいいのでしょうか。
ご教授いただけると幸いです。
よろしくお願いいたします。

以下ソース

C++

1//------------------------------------------------------------------------------ 2// ダイヤログ初期化処理 3//------------------------------------------------------------------------------ 4BOOL CZyuSyoDlg::OnInitDialog() 5{ 6 CDialogEx::OnInitDialog(); 7 8 // "バージョン情報..." メニューをシステム メニューに追加します。 9 10 // IDM_ABOUTBOX は、システム コマンドの範囲内になければなりません。 11 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); 12 ASSERT(IDM_ABOUTBOX < 0xF000); 13 14 CMenu* pSysMenu = GetSystemMenu(FALSE); 15 if (pSysMenu != NULL) 16 { 17 BOOL bNameValid; 18 CString strAboutMenu; 19 bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX); 20 ASSERT(bNameValid); 21 if (!strAboutMenu.IsEmpty()) 22 { 23 pSysMenu->AppendMenu(MF_SEPARATOR); 24 pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); 25 } 26 } 27 28 // このダイアログのアイコンを設定します。アプリケーションのメイン ウィンドウがダイアログでない場合、 29 // Framework は、この設定を自動的に行います。 30 SetIcon(m_hIcon, TRUE); // 大きいアイコンの設定 31 SetIcon(m_hIcon, FALSE); // 小さいアイコンの設定 32 33 // TODO: 初期化をここに追加します。 34 35 make_queue(); 36 37 m_List.InsertColumn(0, "No." , LVCFMT_CENTER, 35); //No列を追加 38 m_List.InsertColumn(1, "性別", LVCFMT_CENTER, 45); //性別列を追加 39 m_List.InsertColumn(2, "名前", LVCFMT_CENTER, 70); //名前列を追加 40 m_List.InsertColumn(3, "年齢", LVCFMT_CENTER, 35); //年齢列を追加 41 m_List.InsertColumn(4, "住所", LVCFMT_LEFT, 200); //住所列を追加 42 43 CEdit* pEditName = (CEdit *)GetDlgItem( IDC_NAME_I ); 44 CEdit* pEditHome = (CEdit *)GetDlgItem( IDC_HOME_I ); 45 CEdit* pEditTosi = (CEdit *)GetDlgItem( IDC_TOSI_I ); 46 47 //エディットボックスに入力できる文字数を設定する 48 pEditName->LimitText(14); 49 pEditHome->LimitText(70); 50 pEditTosi->LimitText(3); 51 52 53 54 return TRUE; // フォーカスをコントロールに設定した場合を除き、TRUE を返します。 55} 56 57//------------------------------------------------------------------------------ 58// キューの生成 59//------------------------------------------------------------------------------ 60void CZyuSyoDlg::make_queue() 61{ 62 struct Queue *que; 63 64 for( int count=0; count<256; count++ ) 65 { 66 //キューの生成 67 if( count == 0 ) 68 { 69 que = (struct Queue*)malloc(sizeof(struct Queue)); // メモリの確保 70 m_pQueue = que; // 先頭をメンバ変数 71 } 72 else 73 { 74 que->next = (struct Queue*)malloc(sizeof(struct Queue)); // ポインタを繋ぐ 75 que = (struct Queue*)que->next; // nextの値をqueに 76 } 77 que->next = NULL; // nextにNULL 78 memset(que, 0, sizeof(struct Queue)); // クリア 79 } 80} 81 82//------------------------------------------------------------------------------ 83// キューの解放 84//------------------------------------------------------------------------------ 85void CZyuSyoDlg::QueClose() 86{ 87 struct Queue *que; 88 que = m_pQueue; 89 while( 1 ) 90 { 91 m_pQueue = (struct Queue*)que->next; 92 free( que ); 93 que = m_pQueue; 94 if( que == NULL ) 95 { 96 break; 97 } 98 } 99} 100 101//------------------------------------------------------------------------------ 102// キューの切り離し 103//------------------------------------------------------------------------------ 104struct Queue* CZyuSyoDlg::QueCut() 105{ 106 struct Queue *head; 107 108 // キューを切り離す(先頭) 109 if( m_pQueue != NULL ) 110 { 111 head = m_pQueue; 112 m_pQueue = (struct Queue*)head->next; //次の先頭 113 } 114 return( head ); 115} 116 117//------------------------------------------------------------------------------ 118// データキューを繋ぐ 119//------------------------------------------------------------------------------ 120void CZyuSyoDlg::QueData(struct Queue *head) 121{ 122 if( m_pQueue2 == NULL ) 123 { 124 m_pQueue2 = head; 125 } 126 else 127 { 128 struct Queue *data; 129 data = m_pQueue2; 130 while( 1 ) 131 { 132 if( data->next == NULL ) 133 { 134 data->next = head; 135 break; 136 } 137 data = (struct Queue*)data->next; 138 } 139 } 140 head->next = NULL; 141 142} 143 144//------------------------------------------------------------------------------ 145// 送信ボタン押下処理 146//------------------------------------------------------------------------------ 147void CZyuSyoDlg::OnBnClickedGo() 148{ 149 struct Queue *head; 150 head = QueCut(); 151 152 CStdioFile ZyuSyoFile; 153 //テキストファイルを開く 154 ZyuSyoFile.Open("ZyuSyoData.txt",CFile::modeReadWrite | 155 CFile::shareDenyNone | CFile::modeCreate | CFile::modeNoTruncate); 156 157 ZyuSyoFile.SeekToEnd(); 158 159 //------------// 160 //名前部の取得// 161 //------------// 162 CString strName; 163 ((CEdit*)GetDlgItem(IDC_NAME_I))->GetWindowText( strName ); 164 //CString → charへの変換 165 strcpy_s( head->data.name, strName ); 166 167 //------------// 168 //住所部の取得// 169 //------------// 170 CString strHome; 171 ((CEdit*)GetDlgItem(IDC_HOME_I))->GetWindowText( strHome ); 172 strcpy_s( head->data.home, strHome ); 173 174 //------------// 175 //年齢部の所得// 176 //------------// 177 CString strTosi; 178 ((CEdit*)GetDlgItem(IDC_TOSI_I))->GetWindowText( strTosi ); 179 strcpy_s( head->data.tosi, strTosi ); 180 181 //------------// 182 //Noの所得 // 183 //------------// 184 CString strNo; 185 m_Combo.GetLBText(m_Combo.GetCurSel(),strNo); 186 strcpy_s( head->data.no, strNo ); 187 188 //----------------// 189 //性別の取得(男性)// 190 //----------------// 191 CString strType; 192 if( ( (CButton*)GetDlgItem(IDC_RADIO_B) )->GetCheck() == BST_CHECKED ) 193 { 194 strType = ("男性"); 195 strcpy_s( head->data.type, strType ); 196 } 197 198 //----------------// 199 //性別の判定(女性)// 200 //----------------// 201 if( ( (CButton*)GetDlgItem(IDC_RADIO_G) )->GetCheck() == BST_CHECKED ) 202 { 203 strType = ("女性"); 204 strcpy_s( head->data.type, strType ); 205 } 206 207 //----------------// 208 //リストへ追加 // 209 //----------------// 210 // リストコントロール 行の追加 211 int count = m_List.GetItemCount(); 212 m_List.InsertItem(count, strNo); //No行を追加 213 m_List.SetItem(count, 1, LVIF_TEXT, strType, 0, 0, 0, 0); //性別行を追加 214 m_List.SetItem(count, 2, LVIF_TEXT, strName, 0, 0, 0, 0); //名前列を追加 215 m_List.SetItem(count, 3, LVIF_TEXT, strTosi, 0, 0, 0, 0); //年齢行を追加 216 m_List.SetItem(count, 4, LVIF_TEXT, strHome, 0, 0, 0, 0); //住所行 217// CDialog::OnOK(); 218 219 //----------------// 220 //ファイル入出力 // 221 //----------------// 222 //テキストファイルに書き込む 223 ZyuSyoFile.WriteString( "No:" + strNo + "|" ); 224 ZyuSyoFile.WriteString( "性別:" + strType + "|" ); 225 ZyuSyoFile.WriteString( "名前:" + strName + "|" ); 226 ZyuSyoFile.WriteString( "年齢:" + strTosi + "|" ); 227 ZyuSyoFile.WriteString( "住所:" + strHome + "\n" ); 228 229 //テキストファイルを閉じる 230 ZyuSyoFile.Close(); 231 232 233 QueData(head); 234} 235 236//------------------------------------------------------------------------------ 237// クリアボタン押下処理 238//------------------------------------------------------------------------------ 239void CZyuSyoDlg::OnBnClickedClear() 240{ 241 //エディットボックス内をクリアする 242 CEdit* pEdit = (CEdit *)GetDlgItem( IDC_NAME_I ); 243 CEdit* pEdit1 = (CEdit *)GetDlgItem( IDC_HOME_I ); 244 CEdit* pEdit2 = (CEdit *)GetDlgItem( IDC_TOSI_I ); 245 246 pEdit ->SetWindowText(""); 247 pEdit1->SetWindowText(""); 248 pEdit2->SetWindowText(""); 249 250} 251 252

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

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

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

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

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

guest

回答3

0

ベストアンサー

1行ずつは読み込めたのですが、ここからどう文字列を分解させればよいのでしょうか。。。

こんなかんじ:

C++

1#include <iostream> 2#include <cstring> 3using namespace std; 4 5int main() { 6 char data[] = "ばんごう:123|なまえ:ゴンベ|くだもの:リンゴ"; 7 8 char* context = nullptr; 9 char* str = data; 10 const char* delim = "|"; 11 for ( char* token = strtok_s(str, delim, &context); 12 token != nullptr; 13 token = strtok_s(nullptr, delim, &context) ) { 14 cout << "step-1: [" << token << "]\n"; 15 16 char* context = nullptr; 17 char* str = token; 18 const char* delim = ":"; 19 cout << " step-2: "; 20 for ( char* token = strtok_s(str, delim, &context); 21 token != nullptr; 22 token = strtok_s(nullptr, delim, &context) ) { 23 cout << "[" << token << "] "; 24 } 25 cout << endl; 26 } 27}
step-1: [ばんごう:123] step-2: [ばんごう] [123] step-1: [なまえ:ゴンベ] step-2: [なまえ] [ゴンベ] step-1: [くだもの:リンゴ] step-2: [くだもの] [リンゴ]

投稿2016/11/08 02:11

episteme

総合スコア16614

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

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

NaokiPooh

2016/11/08 02:45

回答ありがとうございます! この場合は読み込んだ文字列をchar型に変換しなければだめということでしょうか??
NaokiPooh

2016/11/08 04:38 編集

アドバイスのおかげで変換はすることができました。 上記の例で分割後の[ばんごう][123][なまえ][ゴンベ][くだもの][リンゴ]とあったときに[123][ゴンベ][リンゴ]だけをリストコントロールに表示させたい場合はどのようにすればよろしいのでしょうか。
NaokiPooh

2016/11/08 05:00

現状のソースコードです。 void CZyuSyoDlg::OnBnClickedFile() { CString strNo; CString strType; CString strName; CString strTosi; CString strHome; //テキストファイルを読み込ませる処理 CStdioFile ZyuSyoFile("ZyuSyoData.txt", CFile::modeCreate | CFile::modeNoTruncate | CFile::modeRead | CFile::typeText); CString ReadFile; char* strFile = new char[ReadFile.GetLength()+1]; ZyuSyoFile.ReadString(ReadFile); strcpy(strFile,ReadFile); char* context = nullptr; const char* delim = "|"; for( char* token = strtok_s(strFile, delim, &context); token != nullptr; token = strtok_s(nullptr, delim, &context) ) { char* context = nullptr; char* str = token; const char* delim = ":"; for( char* token = strtok_s(strFile,delim,&context); token != nullptr; token = strtok_s(nullptr, delim, &context) ) { //分割した文字列をCStringに格納したい int count = m_List.GetItemCount(); m_List.InsertItem(count, strNo); //No行を追加 m_List.SetItem(count, 1, LVIF_TEXT, strType, 0, 0, 0, 0); //性別行を追加 m_List.SetItem(count, 2, LVIF_TEXT, strName, 0, 0, 0, 0); //名前列を追加 m_List.SetItem(count, 3, LVIF_TEXT, strTosi, 0, 0, 0, 0); //年齢行を追加 m_List.SetItem(count, 4, LVIF_TEXT, strHome, 0, 0, 0, 0); //住所行 } } delete[] strFile; }
ardin

2016/11/08 05:01

なぜそこで困るのか。 OnBnClickedGo()内でSetItem使ってますよね。これを使うだけです この状況ならば、それぞれは変数に入っていると思いますから、難しいことではないと思います
NaokiPooh

2016/11/08 05:22

回答ありがとうございます。 LCに表示させるというよりは分割させたデータの必要な部分だけの取得方法がわからない状況です。
episteme

2016/11/08 05:30

内側のfor-loopで、一発めに得られたtokenが項目名、二発めが設定する内容。
ardin

2016/11/08 05:58

forループで1行を分割して項目を取り出しているのだから、 各々のtokenに分割された項目が入っていると思います(パッと見なので・・たぶん) ということは、必要なデータならばstr**に入れていけばよい debugモードでStep実行することで分かりやすくなるかと思います テキストの形式から行くと先に : を区切り文字にして、次の区切り文字を | にしたほうが良いかもしれません
episteme

2016/11/08 06:05 編集

並びが固定されてるのなら"|:"で切り出して"ひとつ飛びに"取り出せば多重loop回さずに済むじゃん。 てかそのくらい考えろよ。
guest

0

ファイルから読み出すのが苦労している点でしょうか?
考え方とヒントだけ示します

いろいろな方法があると思いますが、そのうちの一つ
上記のフォーマットだとして
ファイル読み込み時に、1行ずつ読み込み、| を区切り文字として扱って分解
No:
性別:
名前:
年齢:
住所:
の文字列を読み出した文字列から消去し、各々の項目を格納する変数に渡す

で、各々使う関数ですが
CStdioFileを使えるようなので、メンバ関数ReadStringを使えます
sprintf_sを使用してバッファに詰め込み、strtok_sで区切り文字で分解
CStringのメンバ関数で消去または抽出しましょう

ソースは示しませんが、上記のものを使用することで実現できるかと思います

投稿2016/11/07 06:00

ardin

総合スコア544

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

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

NaokiPooh

2016/11/08 01:44

回答ありがとうございます! CStdioFile ZyuSyoFile("ZyuSyoData.txt", CFile::modeCreate | CFile::modeNoTruncate | CFile::modeRead | CFile::typeText); CString ReadFile; ZyuSyoFile.ReadString(ReadFile); 1行ずつは読み込めたのですが、ここからどう文字列を分解させればよいのでしょうか。。。 strok_sの使い方がいまいちぴんとこずご迷惑おかけします。
guest

0

  1. ファイルから一行読む
  2. | で区切る
  3. 2の結果をさらに:で区切る
  4. 3の結果から"どのコントロールに" "どんな値を書くか" がわかるから、それに従う

投稿2016/11/07 05:48

episteme

総合スコア16614

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問