• ベストアンサー

CStdioFile での数値データの読みこみ

VC++ で MFC アプリケーションを作っています。 数字の入ったファイル,たとえば以下のような suuji.dat です。 int 型の数字が 5 つ入っています (実際のプログラムで私が使っているのは double 型ですが…) 。 /**  * suuji.dat の始まり  */ 1 2 3 4 5 /**  * suuji.dat の終わり  */ これを CStdioFile で読み込むとき,以下のような方法をとっています。   int num;   CString temp;   CStdioFile file;   while ( file.ReadString(temp) ) {     num = atof(temp);     ここで num を vector<int> に収納する   }   file.Close(); 上の方法は,流れとして, ○とりあえず CString 型として読みこみ   ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ○ atof() 関数によって数値データとして使う   ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ という方法を使っていますが,すごく遠回りなことをしている気分になります。 まだ “Hello, world!” を動かして 4 ヶ月たらずのビギナーです。 プログラミングの作法とかは,ぜんぜん分かっていません。 もし CStrioFile で数値を読み込む,もっとシンプルな方法があればご教授いただけると幸いです。

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

  • ベストアンサー
  • MrBan
  • ベストアンサー率53% (331/615)
回答No.2

CStdioFileに固執しないなら、std::ifstreamから >> という手もあると思います。 更にSTL側に一歩進むと、例えばファイルに /* */等のコメントが無くて数字だけなら、一行で書けます。 #include <fstream> #include <vector> #include <algorithm> #include <iostream> int main(int argc, char* argv[]) { std::cout << "いずれも、ファイルフォーマットが保証できる前提。" << std::endl << "コメントは考慮してない(数値のみに対応)" << std::endl << "エラー処理もやっつけ" << std::endl << std::endl; { std::cout << "std::ifstreamを使うとatoiは不要。" << std::endl; std::ifstream file("suuji.dat", std::ios::in); if( ! file || !file.is_open()) return -1; std::vector<int> data; int num; while(file >> num) { data.push_back(num); } std::cout << "結果" << std::endl; for(std::vector<int>::iterator itr=data.begin(); itr != data.end(); ++itr) { std::cout << *itr; } std::cout << std::endl; } { std::cout << "STLを使うと更に短縮、numも不要" << std::endl; std::ifstream file("suuji.dat", std::ios::in); if( ! file || !file.is_open()) return -1; std::vector<int> data; std::copy(std::istream_iterator<char>(file), std::istream_iterator<char>(), std::back_inserter(data)); std::cout << "結果" << std::endl; std::copy(data.begin(), data.end(), std::ostream_iterator<char>(std::cout)); } return 0; }

k1220011_2005
質問者

お礼

ご回答くださり,ありがとうございます。

その他の回答 (2)

  • MrBan
  • ベストアンサー率53% (331/615)
回答No.3

> 普通、double型の数値を自分でファイルにI/Oするならテキストじゃなくてバイナリ形式で保存しませんか? > バイナリ形式なら、atofの変換作業は発生しませんよ。 マルチプラットフォームだと、doubleのバイナリは内部形式が保証できないので、 あえて文字にシリアライズということはあるかと思います。

k1220011_2005
質問者

お礼

> マルチプラットフォームだと、doubleのバイナリは内部形式が保証できないので 今後バイナリ形式でトライするために,頭の片隅に保存しておきます。 アドバイスありがとうございました。

  • t_nojiri
  • ベストアンサー率28% (595/2071)
回答No.1

>という方法を使っていますが,すごく遠回りなことをしている気分になります。 んー。元データがテキスト形式なら仕方無いですね。 普通、double型の数値を自分でファイルにI/Oするならテキストじゃなくてバイナリ形式で保存しませんか? バイナリ形式なら、atofの変換作業は発生しませんよ。

k1220011_2005
質問者

お礼

ご回答くださり,ありがとうございます。 バイナリで保存するというアイデアは,ちょっと浮かびませんでした。 バイナリ形式というものは知っていたのですが… 確かに数値データをバイナリで保存するという手段もありましたね。 ごく自然なことながら,指摘いただいて大変驚きました。 今の自分にはハードルがやや高いので,今後の挑戦課題としてキープしておきます。 ありがとうございました。

関連するQ&A

  • 文字型配列に数値を文字として代入したいです

    掲題の通りですが、listという配列に数値や文字を入れたいです。 数値は必ず整数1桁、文字はAかBの1文字です。 配列は char list[] = new char[8]; として定義しています。 numにAかBを入れると、代入も表示もうまくいきます。 しかし、数値を入れると以下のような動作となります。 list[i] = num とすると 「不適合な型: 精度が失われる可能性があるintからcharへの変換」 というエラーが表示されます。 list[i] = (char)num; に変更するとエラーは出ませんが、表示がうまくされません。 list[i] = String.valueOf(num); に変更すると 「エラー: 不適合な型: Stringをcharに変換できません:   list[i] = String.valueOf(num);」 というエラーが表示されます。 何か良い方法はないでしょうか。

  • id指定した数値同士を合計計算し表示する方

    素人の投稿ですみませんがご教授いただけましたら幸いです。 id指定した数値同士を自動で合計計算し表示する事は出来ますでしょうか? やりたいことで一番近かった投稿は以下のものです。 「テーブル内に表示されている数字の自動計算について」 http://okwave.jp/qa/q5295498.html 上記の場合、テーブルセルの縦列の合計が自動で表示されるのですが、既にWEBサイトが出来上がっており新たにテーブルを組み込むことが出来ません。 例えばidを使用し <span id="suuji">10000</span> <span id="suuji">20000</span> <span id="total">30000</span> という風にid=suujiで指定した数値をid=total指定した場所へ合計表示させることは出来ますでしょうか? 出来ればid=suujiは1つだけの方が有難いのですが、難しければsuuji1、suuji2、suuji3と分かれても構いません。 お忙しい中、大変難しいご質問ですが何卒宜しく御願い致します。

  • 数値をASCII文字にする方法についての質問です。

    数値をASCII文字にする方法についての質問です。 PICマイコンのプログラミングをするために、C言語を使用しています。LCDに数値を表示するには変数を数値ではなく文字で渡してやらないといけないようなのですが、その変換のしかたがわからず調べていると、あるサイトで二桁の数字(suuji)の1の位をASCII文字(hensu)にするために、 hensu = (suuji % 10) + '0'; のようにコードを記載していました。実際にこの通りプログラミングしてみるとLCDに表示されたのですが、なぜこのようにするとASCII文字に変換できるのかがわかりません。('0'を加えるとアスキー文字になるのでしょうか?)どなたか教えて頂ければと思います。

  • 数値から文字列へ変換後の先頭桁埋めについて

    お世話になっています。 現在csvファイルからデータを読みだして、 読みだした項目をphp上で表示させようとしています。 例として page1.php <?php $num = '100'; #csvから取得した数値項目 $temp = "00" + $num; ?> と記述して値を引き渡したものを page2.php <html> <body> <?= $temp; ?> </body> </html> というように記述しても先頭の00が自動で省略されてしまいます。 画面上に'100'という数値自体は表示できていますが、 数値の変数を先頭に'0'の足して文字列として使用するにはどのようにすれば良いのでしょうか? strval($num)を使用してもやはり正しい値が表示されませんでした。 ぜひ知恵をおかしください。 以上、宜しくお願いします。

    • ベストアンサー
    • PHP
  • テキストファイルの内容を配列に格納したい

    <プログラム環境> Windows XP VC++6.0 MFC AppWizard(exe) ダイアログベース <質問> テキストファイルの内容(数字)を読み込み、double[][]に格納 する方法はありますか? 以下のソースではxxx.txtの内容をCStringで取得・表示できたのですが、 文字を数字に変換し、数字を一つずつdouble[][]に格納したいです。 例えば double[0][0] = 0; double[0][1] = 1; double[1][2] = 5; のように格納したいです。 <現時点でのソース> void CMyDlg::OnReadText() {  CString csBuf;  CStdioFile ifp;  m_Display = "";//m_Displayはエディットボックスのメンバ変数  if(ifp.Open("xxx.txt",CFile::modeRead)==NULL) return;  while(TRUE){   if(ifp.ReadString(csBuf)==NULL) break;   m_Display += csBuf + "\r\n";  }  UpdateData(FALSE);UpdateWindow();  ifp.Close(); } <xxx.txt>   0  1  2   3  4  5   6  7  8   9 10  11  12  13  14 数字はタブで間隔が開いています。 宜しければご指摘お願い致します。

  • 標準出力をDOS窓を開かずにファイルに書き込む方法

    VC++(Console Appli)です。 あるコマンドの標準出力結果をファイルに吐き出す方法として、 単純には、 system("cmnd > C:\\temp.txt"); とやれば実現できますが、このとき、一瞬ですが、DOS窓の黒枠が表示されます。 このDOS窓を出さないで済む方法があれば教えてください。 標準出力を何らかの方法で受け取って、 ------------------------------------------------- CString str; CStdioFile file;   :  cmndの標準出力結果をstrへ内部的に受け取らせる。   : file.Open(_T("c:\\temp.txt"), CFile::modeWrite); file.WriteString(str); file.Close(); ------------------------------------------------- などで簡単に出来れば良いのですが・・よろしくお願いします。

  • Run-Time Check Failure #3というエラーが出ます。

    //Run-Time Check Failure #3 - The variable 'Data' is being used without being defined. //というエラーが出ます。どうしたらいいですか? //プログラムの内容は、数値を格納するときに、二分木構造で格納していくというものです。 //多分違うような気がしますが、、 //よろしくお願いします。 #include<stdio.h> struct DATA { DATA *Small; DATA *Large; int Number; }; void InputData(DATA *Dat,int num) { if(Dat==NULL){Dat=new DATA;Dat->Number=num;return;} if(Dat->Number<num) { Dat->Large=new DATA; Dat=Dat->Large; InputData(Dat,num); } else if(Dat->Number>num) { Dat->Small=new DATA; Dat=Dat->Small; InputData(Dat,num); } return; } int main() { DATA *Data; InputData(Data,20);//<-ここでエラーが出ます。 InputData(Data,10); InputData(Data,30); return 0; }

  • VC++のプログラミングについて

    VC++(verson2003)でテンプレートはMFCのダイアログベースでアプリケーションを作成しています。以下のプログラムはあるボタンをクリックしたときに呼び出される関数でエディット(コントロール変数m_edit1)に入力されたファイル名の内容(メモ帳に記述したテキスト文)を変数textに格納するものです。このプログラム書き換えてメモ帳に 3 1 4 9 のように記述した数字をint型の一次配列に格納するようにしたいのですがどのようにすればよいでしょうか。 void CprogramDlg::OnBnClickedButton1() { CStdioFile fin; char buf[1001]; CString text,filename; m_edit1.GetWindowText(filename); if (filename == "") return; if(!fin.Open(filename, CFile::modeRead | CFile::typeBinary)) {  AfxMessageBox("読み込みファイルをオープンできません");  return; } text = ""; while (fin.ReadString(buf,1000) != NULL) { text = text + buf; } fin.Close(); }

  • int型(2バイト)データの分割

    int型(2バイト)データの分割 マイコンのフラッシュ領域にint型のデータ(2バイト)を 1バイトづつ書き込むのに以下のコードを考えています。 unsigned int data; unsigned char dat1,dat2; data = 555; dat1 = 0; dat2 = 0; dat1 = (char)data; dat2 = (char)data >> 8; 以下、dat1とdat2をフラッシュに書き込む。 未熟者でプログラムとして合っているのか解りません。 やり方として問題ないでしょうか? またもっと良い方法があればご教授願います。

  • 文字列数値化

     ちょっとした事情によりint型で作った数字の文字列をC言語で数値化する方法を教えてください。 よろしくお願いします。

専門家に質問してみよう