ファイルの中身を表示させるプログラムを書いています。#includeヘッダーとか抜いてます。
以下のように実行すると「test samplee」とeという一番最後の文字が2つ連続で出てきました。
しかし、test sampleの後ろに改行を入れると正しく「test sample」と出力されました。
なぜ改行を入れなかった場合は最後の文字が連続して出力されたのでしょうか?
//main.cpp
int main(){
ifstream inf("test" , ios::in | ios::binary);
char ch;
while(!inf.eof()){
inf.get(ch);
cout << ch;
}
inf.close();
}
//test
test sample
A 回答 (4件)
- 最新から表示
- 回答順に表示
No.1
- 回答日時:
本当に改行を入れたら「正しく」出力されたのかな?
さておき, これは C でもよくやる「間違い」の 1つ. EOF かどうかは読み込んでみないとわからないので
読み込んでから EOF でないかどうかをチェック
しないといけない.
このプログラムのように
EOF でなかったら読み込む
という形にすると「EOF かどうか」の判定が 1文字分遅れる. 実際にこのプログラムではその影響が「一番最後の文字が2つ連続で出てきました」という形で現れている.
改行を入れたら正しく出力されたのは環境的な問題ですかね?参考書通りやってみたのでおそらくは環境的何なかかと…
EOFに関してですが読み込んでからチェックするならこれでも大丈なのでしょうか?もっといい方法があれば教えてください。
while(1){
if(inf.eof()) break;
inf.get(ch);
cout <<ch;
}
No.2
- 回答日時:
> 環境的な問題ですかね?
いいえ。
改行無しのときと同じ動作をしています。
https://ja.cppreference.com/w/cpp/io/basic_istre …
> basic_istream& get( char_type& ch ); (2)
> 2) 文字をひとつ読み込み、利用可能であればそれを ch に格納します。 そうでなければ、 ch は変更されず、 failbit および eofbit をセットします。
> 戻り値
> 2-6) *this。
ということで。
最後の文字を読む // 改行無しのときは ch='e' 改行有りの場合は ch='\n'
chを出力 .. (i)
次のループへ
eof = false (この時点では)
文字を読もうとして失敗する // 改行無しのときは ch='e' 改行有りの場合は ch='\n' のままで変更されない
chを出力 .. (2)
次のループへ
eof = true →ループ終了
と動作しています。
改行有りが正しそうに見えたのは、「最後の文字が2つ出力される」の「最後の文字」が「改行」という「目に見えない文字」なために2つ出力されていることに気付かなかった、ということです。
本来は
test sample(改行)
と出力して欲しいところを
test sample(改行)
(改行)
と1行余分に出力されています。
while(1){
if(inf.eof()) break; // チェックしてから
inf.get(ch); // 読み込む
cout <<ch;
}
これは、元のプログラムを同じです。
「EOFに関してですが読み込んでからチェックする」のですから
while(1){
inf.get(ch); // 読み込んでから
if(inf.eof()) break; //チェックする
cout <<ch;
}
でないと。
検索したり参考書を読んだりすると出てくるのは
while(inf.get(ch)){
cout <<ch;
}
というものです。
get(char &)の戻り値は *this (つまり、ifs自身)
→ whileの条件なので boolと解釈される
→ https://ja.cppreference.com/w/cpp/io/basic_ios/o …
という流れで、「読み込んでから判定」を行います。
C言語の while( (c=fgetc(fp)) != EOF ) みたいな感じです。
No.3
- 回答日時:
元プログラムだと EOF しかチェックしていないので, それに合わせるなら while の条件は
! inf.get(ch).eof()
なのかもしれない.
ただし inf.get(ch) の方が安全.
No.4
- 回答日時:
inf.get(ch);
cout << ch;
と続いているので、eof などで読み込み失敗したときも、cout << ch;しているというだけでしょう。
普通、バグというやつです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C++のcinの動作 5 2023/02/26 00:13
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- その他(プログラミング・Web制作) VScodeでpythonプログラムの関数を実行したい 2 2022/07/13 19:24
- Visual Basic(VBA) あるフォルダーのファイルを違う親フォルダーのサブフォルダーに移したい 11 2023/02/15 19:00
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# 質問です 下記のコードを分かりやすく解説お願いします 初心者です #include ‹stdio.h 3 2022/05/26 22:03
- C言語・C++・C# プログラミングの問題です。至急教えてください。 /***から***/の部分をプログラミングにしてほし 1 2022/10/13 11:48
- Excel(エクセル) フォルダ内のエクセルファイルを開かずにデータ採取する関数式 2 2022/12/22 22:15
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- Wi-Fi・無線LAN PCWi-Fiの設定方法がわからなくて困っています。 4 2022/12/28 18:30
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBAのコマンドボタンの文字列の...
-
テキストファイルから改行コー...
-
C++で空Enterの入力を判...
-
LaTeX: captionの中で改行した...
-
JAVA System.out.println の ...
-
fgetsとsscanf
-
エスケープ文字の復帰(¥r)と...
-
VBAでCSVをExcelに取り込む時に...
-
VB6でブラウザのページソースを...
-
C++のctime関数復帰値の改行
-
【Tex】\\verbatiminputについて
-
Excel VBS、ADODB.Streamで改行
-
VBでcsv読込TextFieldParser...
-
エディットボックスで改行
-
C++Builderでの文字化け
-
最終行の改行について
-
ソースコードの1行が長いとき...
-
掲示板で改行されない
-
改行について
-
vbsで2文字以上の空白を改行に...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBAのコマンドボタンの文字列の...
-
ソースコードの1行が長いとき...
-
エスケープ文字の復帰(¥r)と...
-
ファイルから読み取った改行文...
-
JAVA System.out.println の ...
-
C++で空Enterの入力を判...
-
COBOLの改行
-
テキストファイルから改行コー...
-
改行について
-
【VBA】エクセルで最後の不要な...
-
1行ごとに取得して、その改行...
-
jsp 改行コードで改行させて表...
-
VBAでCSVをExcelに取り込む時に...
-
エクセルVBA 文字列領域が不足...
-
最終行の改行について
-
改行を読み飛ばす
-
コンボボックスの項目中に改行を
-
ExcelVBAでメールを作成してメ...
-
テキストボックス行の桁数を制...
-
JavaMail,本文中の改行について
おすすめ情報