質問
このコードを使用して、文字列「Foo」をバイナリ形式で10回印刷しようとしました。しかし、なぜそれを行う機能が機能しないのでしょうか?
#include <iostream>
#include <fstream>
using namespace std;
template <typename T> void WriteStr2BinFh (string St, ostream &fn) {
for (unsigned i = 0; i < St.size(); i++) {
char CStr = St[i];
fn.write(&CStr.front(), CStr.size());
}
return;
}
int main() {
string MyStr = "Foo";
ofstream myfile;
myfile.open("OuputFile.txt", ios::binary|ios::out);
// We want to print it 10 times horizontally
// separated with tab
for (int i = 0; i < 9; i++) {
WriteStr2BinFh(Mystr+"\t", myfile);
}
myfile.close();
}
解決
ここではそんなに間違ってありますが、私はちょうど私が見るすべてをリストアップするつもりです。
あなたのループのための条件は、私は<10である必要があります。
なぜあなたはテンプレートではなく、テンプレートパラメータTを使用していますか?
あなたは、CStr関数のメソッドの前に()を呼び出していますが、CStr関数は、char、文字列ではありませんので、私もそれがコンパイル方法を知りません。
CStr関数は、あなたの代わりにあなたが何かを言いたい、と使用してフロント()反復子のアドレスを取得したくない文字列だったと仮定します:
fn.write(St.c_str(), St.size());
そして、あなたはSt.size()の反復のためにループにしたくありません。ただ、上記の操作を行います。
他のヒント
ああ、エラーがたくさんあります:
- int main - 値を返す必要があります。
- 関数では template< typename T > を使用しません。
- Mystr - 関数呼び出し内の名前が正しくありません。C++ の名前は大文字と小文字が区別されます。
- char CStr - メソッド フロントがなく、std::string もありません。
- ベクトルの場合など、最初の要素のアドレスを取得できませんでした。
- std::string を const 参照として受け入れるとより良いでしょう。
- 文字列ヘッダーを含めるのを忘れました。
- ...
コードの構成と名前付けを使用して例を修正しました。
#include <iostream>
#include <fstream>
#include <string>
void WriteStr2BinFh( const std::string& St, std::ostream &out )
{
out.write( St.c_str(), St.size() );
}
int main()
{
std::string MyStr = "Foo";
std::ofstream myfile( "OuputFile.txt", std::ios::binary | std::ios::out );
for (size_t i = 0; i < 9; ++i)
{
WriteStr2BinFh( MyStr+"\t", myfile );
}
myfile.close();
return 0;
}
しかし、私は使用することをお勧めしました std::fill_n
アルゴリズム
std::fill_n( std::ostream_iterator< std::string >( myfile, "\t" ), 10, MyStr );
まず、char CStr
は、単一の文字CStr
であると述べています。第二に、fn.write(&CStr.front(), CStr.size());
はもちろんコンパイルすることはできませんstd::vector<>
、同様に、コンテナとしてその文字を扱います。
私がチェックしていないこれ、WriteStr2BinFh
にすべてアップがOKであると仮定すると、これはWriteStr2BinFh
が見える(可能性)する方法であります
void WriteStr2BinFh(const string& St, ostream &fn)
{
for(string::iterator it = St.begin(); it != St.end(); ++it)
{
fn.put(*it);
}
}
又は、好ましくは
void WriteStr2BinFh(const string& St, ostream &fn)
{
fn.write(St.c_str(), St.length());
}
バイナリ モードで io 操作を実行する場合の重要な点:
- ファイルは、フラグ ios::out (出力モード) および ios::binary( バイナリ モード) を使用して、出力モードおよびバイナリ モードで開く必要があります。
- 関数 write は 2 つのパラメータを取ります。最初のパラメータは書き込まれるデータの char* 型で、2 番目のパラメータはバイナリ ファイルに書き込まれるデータのサイズを要求する int 型です。
ファイルは最後に閉じる必要があります。
void write_to_binary_file(WebSites p_Data) { fstream binary_file("c:\\test.dat",ios::out|ios::binary|ios::app); binary_file.write(reinterpret_cast<char *>(&p_Data),sizeof(WebSites)); binary_file.close(); }
この I/O バイナリ関数は、関数にデータを書き込みます。
ファイルは、ios::out および ios::binary を使用して出力およびバイナリ モードで開かれます。もう 1 つ指定子 ios::app があり、これはファイルが追加モードでも開かれることをオペレーティング システムに指示します。これは、新しいデータセットがファイルの最後に追加されることを意味します。
上記で使用した書き込み関数には、文字ポインタ型としてパラメータが必要です。そこで、型コンバータ reinterpret_cast を使用して、構造体を char* 型に型キャストします。