こんにちは。
C++について質問させて下さい。
コンパイラは、Borland C++ Compiler 5.5 を使用しています。
僕は、ifstreamとfstreamクラスは、istreamクラスから派生していると認識しています。
つまり、istream型のポインタや参照は、ifstream型オブジェクトもfstream型オブジェクトも指す事ができるはずです。
その事を確認するために、まず、以下のような内容の入力マニピュレータを作成しました。
------------------------------------------------------------
istream &alphabet(istream &stream)
{
char ch;
do{
ch=stream.peek();
if(!isalpha(ch))
stream.get(ch);
}while(!isalpha(ch) && !stream.eof() );
return stream;
}
------------------------------------------------------------
この入力マニピュレータは、
ifstream fin("test.txt");
のようにして作成されたifstream型オブジェクトのfinと、
char str[80];
のようにして作成された文字列変数strに対して、
fin >> alphabet >> str;
のように使うと、finに結び付けられたファイルtest.txtの現在位置(getポインタの位置)から、
次にアルファベットが現れるまで、アルファベット以外の文字を捨て去ることで、
アルファベットではじまる単語をstrに格納する事ができます。
また、この入力マニピュレータは、istream型オブジェクトへの参照を受け取るので、
fstream finout("test.txt");
のようにして作成されたfstream型オブジェクトのfinoutに対して、
fin >> alphabet >> str;
のように使っても、問題なく動作しました。
つまり、上のマニピュレータの場合は、istream型オブジェクトへの参照を、
引数として受け取るようにしてあるので、istreamクラスから派生している、
ifstreamクラスのオブジェクトや、fstreamクラスのオブジェクトを渡す事ができています。
次に、以下のような内容の、ifstream型オブジェクトへの参照を受け取る関数を作成しました。
void file_to_str(ifstream &file, char *str)
{
const int size=1000;
char temp[size]="";
do{
file.getline(temp, size);
strcat(str, temp);
if(!file.eof())
strcat(str, "\n");
}while(!file.eof());
}
この関数は、
ifstream fin("test.txt");
のようにして作成されたifstream型オブジェクトのfinと、
char str[1000];
のようにして作成された文字列変数strに対して、
file_to_str(fin, str);
のように使うと、finに結び付けられたファイルtest.txtの内容を、
文字列変数strに格納する事ができます。
ここで、上の関数のプロトタイプを
void file_to_str(ifstream &file, char *str);
から
void file_to_str(istream &file, char *str);
に変更してみると、プログラムをコンパイルした時に、以下のようなエラーが発生します。
------------------------------------------------------------
C:\Users\kei\work\C++
>bcc32 file_to_str.cpp
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
file_to_str.cpp:
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
Error: 外部シンボル 'file_to_str(std::basic_fstream<char, std::char_traits<char>
>&, char *)' が未解決(C:\USERS\KEI\WORK\C++\FILE_TO_STR.OBJ が参照)
------------------------------------------------------------
file_to_str.cppには、上の関数が定義されていて、
そのmain関数の内容は、以下の通りです。
------------------------------------------------------------
void main(void){
ifstream fin("test.txt");
char str[1000];
file_to_str(fin, str);
}
------------------------------------------------------------
コンパイルエラーは、
file_to_str(fin, str);
の行で発生しています。
なぜ、入力マニピュレータの時は、仮引数をistream型オブジェクトへの参照にしてもOKだったのに、
関数の場合はコンパイルエラーが発生するのかが分からず、困っています。
理屈的には、何度も言っているように、istreamクラスからfstreamクラスとifstreamクラスが派生しているので、全然問題が無いように思えます。
何か御存じの方がいらっしゃれば、是非、情報を提供して頂きたく思います。
では、よろしくお願い致します。
No.4ベストアンサー
- 回答日時:
#2のお礼に記載のコードを BCC55でコンパイルorリンクを行いましたが質問のような現象には遭遇しませんでしたよ
一部変更/修正が必要でしたが …
// ヘッダーファイルの指定を追加
#include <iostream.h>
#include <fstream.h>
void file_to_str(istream &file, char *str)
{
const int size=1000;
char temp[size]="";
do{
file.getline(temp, size);
strcat(str, temp);
if(!file.eof())
strcat(str, "\n");
}while(!file.eof());
}
void main(void)
{
// fstreamをifstreamに修正
ifstream file("test.txt");
char str[10000]="";
// 変数pをstrに修正
file_to_str(file, str);
}
といった具合です …
>bcc32 BCSTL001-test.cpp
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
BCSTL002-test.cpp:
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
御回答ありがとうございます。
何が悪かったのか分かりました。
main関数を含むプログラムでインクルードしている、
ヘッダファイルに記述してあるfile_to_str関数のプロトタイプが、
file_to_str(istream &file, char *str);
ではなく、
file_to_str(ifstream &file, char *str);
file_to_str(fstream &file, char *str);
となって事が原因だったようです。
Tacosanさん、redfox63さん
ご協力頂き、ありがとうございました。
No.3
- 回答日時:
それら全体を 1つのファイルにして g++ に食わせたら (いくつか修正しなきゃならんけど) コンパイルできました.
とはいえ, 「main の内容」が違っていたりするのが謎. もとの質問では ifstream なのに, #2 に対して出てきたプログラムだと fstream になってる.
「プロトタイプを変更したプログラム」の全体は本当にそれであってますか? そして, 本当にエラーメッセージはもとの質問に挙がっている通りですか?
Tacosanさん
御返信ありがとうございます。
>「main の内容」が違っていたりするのが謎. もとの質問では ifstream なのに, #2 に対して出てきたプログラムだと fstream になってる.
分かりにくくて申し訳ありません。
#2では、書き換えた方のプログラムを、記載しましたので、
最初の質問フォームに記載したコードは無視してもらっても構いません。
書き換えた方のプログラムで
file_to_str(file, p); の部分が間違っているので
file_to_str(file, str); に修正しておいてください。
あと、
書き換えた方のプログラムで表示されるエラーは、
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
file_to_str-test.cpp:
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
Error: 外部シンボル 'file_to_str(std::basic_fstream<char, std::char_traits<char>
>&, char *)' が未解決(C:\USERS\KEI\DESKTOP\FILE_TO_STR-TEST.OBJ が参照)
です。
>それら全体を 1つのファイルにして g++ に食わせたら (いくつか修正しなきゃならんけど) コンパイルできました.
御手間をお掛けしますが、どのように修正すればよいのか、教えて頂けますでしょうか?
No.2
- 回答日時:
とりあえず「プロトタイプを変更した」あとのプログラムを全部だしてください.
御回答ありがとうございます。
プロトタイプを変更した後のプログラムですね。
file_to_str関数とmain関数の両方を、一応記載しておきます。
-----------------------------------------------------------
void file_to_str(istream &file, char *str)
{
const int size=1000;
char temp[size]="";
do{
file.getline(temp, size);
strcat(str, temp);
if(!file.eof())
strcat(str, "\n");
}while(!file.eof());
}
void main(void)
{
fstream file("test.txt");
char str[10000]="";
file_to_str(file, p);
}
-----------------------------------------------------------
何か分かりましたら、よろしくお願い致します。
No.1
- 回答日時:
コンパイルエラーじゃなくて リンクエラーですよね
ということは 引数書き換えたときに 関数名を変更してしまったなんてことありませんか
今あるブロック(file_to_str)をコメントアウトしておいて
関数をもう一度書いてみてはいかがでしょう
どこかにケアレスミスがあると思うんですけどね …
御回答ありがとうございます。
仰っている内容から考えると、
「僕は、ifstreamとfstreamクラスは、istreamクラスから派生していると認識しています。
つまり、istream型のポインタや参照は、ifstream型オブジェクトもfstream型オブジェクトも指す事ができるはずです。」
という部分は、間違っていないと考えてもいいのでしょうか?
あと、file_to_str関数ですが、プロトタイプの第一引数の型を、ifstream&から
istream& に変更しただけであり、関数名や、その内容は全く変更していません。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBA 同じ名前のオブジェクトを...
-
Excelで =EMBED("Acrobat Docu...
-
パワーポイントのVBAでテキスト...
-
COMコンポーネントって何?
-
ワイルドカード<?>と型パラメー...
-
EXCEL VBAにて動的にCheckBOXを...
-
JAVAからHTMLへ値を返す方法
-
シーケンス図のライフラインと...
-
bmp画像をjpegやpng画像に圧縮...
-
ビジュアルC++でボタンの有...
-
0 == False はいいけど
-
error C2712: オブジェクト ア...
-
時間帯判定をする。
-
ワードで画像をドロップすると...
-
LISTBOXの内容が更新されま...
-
Javaの問題なんですが、(this==...
-
ASP.net 教えてください!!(...
-
C#でフォームのオブジェクト名...
-
Vbで通常使用するプリンターを...
-
Object型からDouble型へのキャスト
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
パワーポイントのVBAでテキスト...
-
VBA 同じ名前のオブジェクトを...
-
Excelで =EMBED("Acrobat Docu...
-
C#でフォームのオブジェクト名...
-
VBAのWindowオブジェクトとWork...
-
EXCEL VBAにて動的にCheckBOXを...
-
時間帯判定をする。
-
ビジュアルC++でボタンの有...
-
COMコンポーネントって何?
-
Object型からDouble型へのキャスト
-
error C2712: オブジェクト ア...
-
LISTBOXの内容が更新されま...
-
ワイルドカード<?>と型パラメー...
-
戻り値がクラスオブジェクト
-
bmp画像をjpegやpng画像に圧縮...
-
VBAからノーツを起動
-
ワードで画像をドロップすると...
-
Accessの連結・非連結オブジェ...
-
CoCreateInstanceでエラーになる。
-
オブジェクトレベルとメタレベル
おすすめ情報