こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

fstream型オブジェクトを関数の仮引数にする

こんにちは。

現在、C++を使ってプログラミングをしているのですが、fstream型・ifstream型・ofstream型のオブジェクトを、関数の仮引数にするにはどうすればよいのか分からず困っています。
具体的に言いますと、まず、main関数の中で
fstream file("test.txt"); のように、fstream型オブジェクトfileを定義しておき、これを以下のような関数に渡して、関数の内部で使いたいのです。
(以下の関数は、ファイルの内容を、1つの文字列変数に格納するためのものです。)
________________________________________________________________________________________________________________________
void file_to_str(fstream file, char *str){
const int size=10000;
str=""; //初期化しとかないとダメ。
char temp[size]=""; //初期化しとかないとダメ。

while(!file.eof()){
file.getline(temp, size); //改行に出会うかsize個の文字を読み込むまで、 //文字をバtemp)に読み込む。
strcat(str, temp);

if(!file.eof()){
strcat(str, "\n"); //getline()関数は改行をバッファに読み込まない。
}

}
}
________________________________________________________________________________________________________________________

この関数を、main関数でfstream file("test.txt"); と記述した直後で呼び出した所、以下のようなエラーが出ました。
________________________________________________________________________________________________________________________
エラー E2247 file_to_str.cpp 48: 'ios::basic_ios(const ios &)' はアクセスできな
い(関数 fstream::basic_fstream(fstream &) )
エラー E2247 file_to_str.cpp 48: 'ios::basic_ios(const ios &)' はアクセスできな
い(関数 iostream::basic_iostream(iostream &) )
エラー E2125 file_to_str.cpp 48: コンパイラは 'copy constructor' クラスの istrea
m を作成できない(関数 iostream::basic_iostream(iostream &) )
エラー E2125 file_to_str.cpp 48: コンパイラは 'copy constructor' クラスの ostrea
m を作成できない(関数 iostream::basic_iostream(iostream &) )
________________________________________________________________________________________________________________________

何かいい方法を知っておられる方がいらっしゃれば、是非アドバイスを頂きたいと思います。
(「このプログラムの場合は、FILE型ポインタで代用できる。」といった答え以外でお願い致します。)

では、よろしくお願い致します。

投稿日時 - 2011-09-07 05:31:35

QNo.6994742

困ってます

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

C++でクラスを使ったプログラミング、どれくらいやってますか?

> void file_to_str(fstream file, char *str)
のように書いたら、値呼び出しなので、fstreamオブジェクトのコピーが作られる、というのは理解してますか?
このようなオブジェクトのコピーに呼び出されるのがcopy constructor(コピーコンストラクタ)です
で、ファイルの管理がばらばらにならないように、コピーできないようにしてあるのが、エラーの原因です。

Cからの方法であるポインタを使うか
void file_to_str(fstream *file, char *str)
(定義中の file.XX → file->XX 、 呼び出しはfile_to_str(&file,str) )

C++で追加された参照呼び出しを使うか
void file_to_str(fstream &file, char *str)

これは、他のオブジェクトでも同様です。fstreamのようにコピーが禁止されているものばかりではありませんが
・コピーに対しての処理でいいのか?処理がいいのか?
・同じオブジェクトに対して処理をしなければならないのか?
を考えて作りましょう。


あと
> str=""; //初期化しとかないとダメ。
これはfile_to_str関数内でのローカル変数 char *str に 文字列リテラル"" のアドレスを入れているだけです。呼び出し側のstrのアドレスがわからなくなってしまうだけでなく、おそらく定数用の領域に確保された文字列リテラル""のアドレスへ書き込もうとします。

ポインタの使いかた、char*を使った文字列の使いかたをもう一度見直しては?

投稿日時 - 2011-09-07 07:05:08

お礼

大変御丁寧な御回答、ありがとうございます。

しばらくC++から遠ざかっていたもので、値呼び出しの時に、コピーコンストラクタが呼び出される事などを忘れていました。
御提案頂いた通り、C++の参照呼び出しを使うと上手く行きました。

「str=""; //初期化しとかないとダメ。」
という1行は、初歩的なミスですね。(笑)
これを消さないと上手く行きませんでした。

適切すぎる御説明、御見事でした。

投稿日時 - 2011-09-07 09:08:00

ANo.1

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(1)

あなたにオススメの質問