バイナリ形式でデータの入出力をしたい

このQ&Aのポイント
  • バイナリ形式でデータを読み書きする方法について教えてください
  • STLやstringが規格化されていない時代の古いC++の本しか持っていない私の唯一の教科書はマイクロソフトのライブラリだけです。しかし、バイナリデータの読み書きについてどこに必要な情報が載っているかわかりません。
  • バイナリファイルの読み込みや書き込みに対して、ifstreamやofstreamを使用していますが、これが正しいやり方なのか確認したいです。特にファイルモードのios::truncについても教えてください。
回答を見る
  • ベストアンサー

バイナリ形式でデータの入出力をしたい

STLやstringが規格化されていない時代の古いC++の本しか持っていない私の唯一の教科書はマイクロソフトのライブラリだけなのですが時々どこに必要な事項が載っているか探しきれないことがあります その1つとして バイナリデータを読み出したり書きこんだりするにはどうするかということです バイナリファイルinfile.exeの読み出のためのファイルとの接続として ifstream ifs; ifs.open("infile.exe",ios::in|ios::binary); としバイナリファイルoutfile.exeの読み出しのためのファイルとの接続として ofstream ofs; ofs.open("outfile.exe",ios::out|ios::binary|ios::trunc); としましたがこれは正しいやり方なのでしょうか? もし不備があれば指摘してください とくにファイル名の次のモードについて指摘していただければ幸いです (なかでもios::truncが心配)

  • nubou
  • お礼率62% (293/470)

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

  • ベストアンサー
回答No.7

> ofs.open("gomi",ios::out|ios::binary); > と書くことが有効な場合はどんな場合でしょうか? ファイルの一部を書き換えたいとき。

その他の回答 (6)

回答No.6

> ...writeするとファイルの末尾に追加されると思ってます?違いますよ。 からどうやって > どちらでもかまわないということですね という結論が導き出せるんだろう...

nubou
質問者

補足

データをつぶして書きたい場合は ofs.open("gomi",ios::out|ios::binary|ios::trunc); と書けば良いことは分かりました では ofs.open("gomi",ios::out|ios::binary); と書くことが有効な場合はどんな場合でしょうか?

回答No.5

> 先頭から12個読み込んでみると0から8だけが取りこまれました > つまり切り詰めなくても0から3は「切り詰められる」ようです ...writeするとファイルの末尾に追加されると思ってます?違いますよ。

nubou
質問者

お礼

上書きしたいときには ofs.open("gomi",ios::out|ios::binary|ios::trunc); とかいても ofs.open("gomi",ios::out|ios::binary); とかいても どちらでもかまわないということですね 詳しく説明ありがとうございました

回答No.4

> 切り詰めるというマイクロソフトの説明も定義が書いていないのでわからないし あれ?僕もMSDN検索しましたが、 app - to seek to the end of a stream before each insertion. ate - to seek to the end of a stream when its controlling object is first created. binary, to read a file as a binary stream, rather than as a text stream. in - to permit extraction from a stream. out, to permit insertion to a stream. trunc - to delete contents of an existing file when its controlling object is created <--- !!! しっかりきっちり書いてあります。

回答No.3

> そもそも切り詰めるとはいったいどう言う意味なのでしょうか? 既存のファイルをオープンしたとき、そのファイルの中身を捨てる(長さを0にする)ってことです。 だからやっぱりバイナリモードとは関係ありません。

nubou
質問者

お礼

いろいろ数値を変えて実験しているのですが 0から3をファイル1に切り詰めて書き込み 0から7をファイル1に切り詰めて書き込みんでも 0から7をファイル1に切り詰めないで書き込みんでも 先頭から12個読み込んでみると0から8だけが取りこまれました つまり切り詰めなくても0から3は「切り詰められる」ようです #include <string> #include <iostream> #include <fstream> using namespace std; void main(void) { int i,j; ifstream ifs; ofstream ofs; string str; char c; unsigned char s[256],z[256]; for(i=0;i<256;i++)z[i]=0; for(i=0;i<256;i++)s[i]=i; ofs.open("gomi",ios::out|ios::binary|ios::trunc); ofs.write(s,4);ofs.close(); ofs.close(); ofs.open("gomi",ios::out|ios::binary); //ofs.open("gomi",ios::out|ios::binary|ios::trunc); ofs.write(s,8);ofs.close(); ofs.close(); ifs.open("gomi",ios::in|ios::binary); ifs.read(z,16);ifs.close(); for(i=0;i<16;i++)cout<<int(z[i])<<","; exit(1); }

回答No.2

> 書きこむ前にファイルデータが存在しても上書きする場合に切り詰める必要はないのですね? なぜやってみないんです? 切り詰めるか否かはバイナリモードとは関係ありません!

nubou
質問者

補足

やってはいるのですが両者の差が検出できないのです 切り詰めつというマイクロソフトの説明も定義が書いていないのでわからないし ちなみに検査プログラムは #include <string> #include <iostream> #include <fstream> using namespace std; void main(void) { int i,j; ifstream ifs; ofstream ofs; string str; char c; unsigned char s[256],z[256]; for(i=0;i<256;i++)s[i]=i; ofs.open("gomi",ios::out|ios::binary|ios::trunc); ofs.write(s,8);ofs.close(); ofs.close(); ofs.open("gomi",ios::out|ios::binary); //ofs.open("gomi",ios::out|ios::binary|ios::trunc); ofs.write(s,16);ofs.close(); ofs.close(); ifs.open("gomi",ios::in|ios::binary); ifs.read(z,16);ifs.close(); for(i=0;i<16;i++)cout<<int(z[i])<<","; exit(1); } です そもそも切り詰めるとはいったい同言う意味なのでしょうか?

回答No.1

問題ないと思います。 ios::truncはバイナリモードとは関係ありません。

nubou
質問者

補足

関係ありません。: ということは ofs.open("outfile.exe",ios::out|ios::binary|ios::trunc); とかくところを ofs.open("outfile.exe",ios::out|ios::binary); としても言いということですね 書きこむ前にファイルデータが存在しても上書きする場合に切り詰める必要はないのですね?

関連するQ&A

  • Cでバイナリデータを変換

    今持っているバイナリファイルfile1.x86をテキストファイルfile1.txtに変換したいんですけどうまくいきません。fopenとfreadでバイナリファイルを読み込むところまで入っていると思うんですけど、テキストファイルとして書き出すことができません。 #include <stdio.h> main() { short a[32000]; FILE *infile, *outfile; infile = fopen("iroha.x86", "r"); outfile = fopen("iroha.dat", "w+"); fread( a, sizeof(short), 32000, infile ); fwrite( a, sizeof(short), 32000, outfile ); fclose(infile); fclose(outfile); } これだとそのまんま出力されるんです。当たり前なんですけど... どこをどう変えればいいか教えてください。 よろしくお願いします。

  • ifstream/ofstream について

    こんにちは。 よろしくお願いいたします。 ifstream で定義したファイルを open し、一端 close した後再度 open しようとすると、エラーとなります。 何が原因かわかりますでしょうか? ちなみに、インファイル.txt は何も記載していないので、下記ソースのwhileループ内には入りません。 が、whileループが有ればエラー(メッセージ:3103)が発生し、 無ければ、エラーは発生しません。 環境:XP home & ボーランドC++Builder6.0 テストしたソース: void __fastcall TForm1::Button6Click(TObject *Sender) { ifstream InFile; ofstream OutFile; char cBuf[255]; InFile.open("インファイル.txt"); if (!InFile) ShowMessage("3101"); OutFile.open("アウトファイル.txt"); if (!OutFile) ShowMessage("3002"); while (!InFile.getline(cBuf, sizeof(cBuf)).eof()) { OutFile << cBuf << endl; } // このwhileループが無ければ、エラーは発生しません。 OutFile.close(); InFile.close(); InFile.open("インファイル.txt"); if (!InFile) ShowMessage("3103"); // ここでメッセージが出力されます。 }

  • ofstream::getがおかしい!

    ofstream::getの動作がおかしいのです #include <string> #include <iostream> #include <fstream> using namespace std; void main(void) { ifstream ifs; ofstream ofs; string str; char c; str="abc"; cout<<"before str: "<<str<<endl<<endl; ofs.open("gomi");ofs<<str;ofs.close(); ifs.open("gomi");for(str="";ifs.eof()==0;str+=c)ifs.get(c);ifs.close(); cout<<"after str: "<<str<<endl<<endl; } の結果が before str: abc after str: abcc になります 最後のcは何でつくのでしょうか? 回避する方法を教えてください

  • ファイル書き込みについて

    いつもお世話になっております。 現在ファイル書き込みをやっているのですが ofstream ofs("hoge", ios::trunc); BYTE byte = 5; ofs << "\"" << byte << "\"" << endl; ofs.close(); とやっても5が書き込まれず""のみとなってしまいます。 BYTEをintに書き換えると"5"と表示されるのですが、今回はBYTE型で書きたいのですが std::ostringstream oss; oss << byte; ofs << oss; とやっても文字化けしてしまいました。 なにかよい方法がありましたらご教授願います。

  • C++のファイルに対する配列データの読み書き

    C++で配列c[0],c[1],....の値をファイルに出力すると、 1.2 3.2 5.1 8.2 -9.1 のようになると思います(この例は配列のサイズが5)。実際は100以上の配列にします。 プログラム的にはだいたい下のようになると思っています。 std::ofstream ofs( "test.txt" ); ofs << ここで並びの出力をするはず? << std::endl; 意味は、出力ファイルの定義とストリームによる書き出し?と改行だと思います。 並びの出力ですから、ループでよいのでしょうか。プログラム作法が分からないので教えて頂きたいのですが。データの区切りは空白で、できれば書く数値のフォーマットは揃えたいですが。 次に、読み込むときはどうなるでしょうか。 std::ifstream ifs( "test.txt" ); std::string str; ifs >> str; std::cout << str << std::endl; これだと読んだデータを画面表示して終わりです。配列に読み込む方法なのですが。 よろしくお願いします。

  • ファイル入出力で

    現在ファイル入出力の項目をしているのですが、以下の内容で実行すると エラーが出てどうしても実行できません。主にどこを直せばいいのでしょうか? /* ファイルをコピーするプログラム */ #include <stdio.h> int main(void) { FILE *fin, *fout; char infile[40], outfile[40]; char str[256]; printf("コピー元ファイル = "); scanf("%39s", infile); printf("コピー先ファイル = "); scanf("%39s", outfile); if( (fin = fopen(infile, "r") ) == NULL) { printf("Input file open error.\n"); return 1; } if( (fout = fopen(outfile, "w") ) == NULL) { printf("Output file open error.\n"); fclose(fin); return 1; } while(fgets(str, sizeof(str), fin) != NULL) { fputs(str, fout); } fclose(fin); fclose(fout); return 0; } エラーは FILE 、fin, fout,NULLの未定義です。 よろしくお願いします。

  • C++でofstreamに空白を含む文字列を<<するとそれ以降の文字が書き込まれない

    以下のようなテストプログラムを書いたのですが、 期待した動作になりません。 #include <fstream> int main() { std::ofstream ofs("C:/test.txt"); char moji[] = "aaa bbb"; ofs << moji << std::flush; ofs.close(); } テキストファイルにはaaaしか書き込まれず、bbbが無視されています。 ifstreamが空白文字までで処理をとめるのは知っていましたが、 ofstreamが書き込む際も同じなのでしょうか。 空白を含む文字列を書き込むにはどうすればよいでしょうか? よろしくお願いいたします。

  • バイナリ

    VB6.0を使っています。 全てのファイル(Word、エクセル、Exe、Txtなどなんでも)はバイナリファイルとして扱えるのですか? バイナリファイルとして読み込んで、別名で保存して、 また、元の形式に戻すにはどのようにしたらよいのでしょうか? バイナリモードでOpenして 1バイトずつ、 バイナリモードで書き込めばいいのでしょうか? また、読む場合は、 バイナリモードで開いて、 1文字ずつ 何モードで書き込めばいいのでしょう? バイナリでいいのですか? ファイルの形式などよくわかっていません。。。。

  • 数値から画像を作りたい

    プログラミング初心者です。 C言語の入門書はとりあえず勉強しました、現在はC++をさわっています。 数値が入っている配列 image[180][180] の値を使ってバイナリ形式の画像を作りたい と考えています。調べてみると下のような書き方をしています ofstream ofs("out.bin", ios::binary); ofs.write(reinterpret_cast<char *>(&a), sizeof(a)); この書き方をすると1ピクセルの値が書き込めるのでしょうか?それぞれの数値の間には ”,”のようなものを入れなくていいのでしょうか?改行はどうすればいいのでしょうか? ヘッダー部分が必要なのでしょうか? 一番簡単に配列の数字からバイナリ形式の画像を作る方法を教えていただきたいです。 宜しくお願いします。

  • [C++]ファイル出力について

    教えてください。 コマンドプロンプトから何行か書いた文章をファイルにしたいのですが、 うまくいきません。 作ったものの結果は1行1文字で出力されて、eofでうまく 終わってくれません。 コマンドプロンプトで入力(改行)された通りにファイルに出力 できるようにしたいので、どこがおかしいのか指摘お願いします。 #include <iostream> #include <fstream> #include <stdlib.h> #include <string.h> #include <string> using namespace std; int main(int argc, char *argv[]) { char str[100]; int i; i = 0; if (argc <= 1) { cerr << "Need filename" << endl; exit (1); } ifstream ifs(argv[1], ios::in); if (ifs) { cerr << "Caution" << argv[1] << " already exists " << endl; cerr << " Specify a different filename " << endl; exit (2); } ofstream ofs(argv[1], ios::out); if (!ofs) { cerr << " Unable to write to " << argv[1] << endl; exit (3); } while(str[i] !=EOF) { cin >> str[i]; ofs << str[i] << endl; i++; } return 0; }

専門家に質問してみよう