質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

3353閲覧

std::ifstream& inFileという引数

reotantan

総合スコア295

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2015/10/28 21:01

std::ifstream& inFileという文がでてきて、
はじめてみる形なので意味がはっきりと理解できませんでした。
!isalnum(letter) && inFileの部分は読み込んだファイルが
存在して、アルファベットと数字によって構成されていないものならもう一度読みこむという意味だと理解していますが、数字とアルファベットではなかった時点で本来の目的は達成されてないからもう一度読み込むのは無駄ではないのかと思いました。
そのあたりも含めて解説していだけると嬉しいです、よろしくお願いします

コード void GetAlphaNum(bool skip, char letters[], std::ifstream& inFile) { using namespace std; char letter; int count = 0; if (skip) { inFile.get(letter); while (!isalnum(letter) && inFile) inFile.get(letter); } else inFile.get(letter); if (!inFile || !isalnum(letter)) letter[0] = '\0'; else { do { letters[count] = letter; count++; inFile.get(letter); } while (isalnum(letter) && inFile && (count < MAX_CHARS)); letters[count] = '\0'; if (count == MAX_CHARS && isalnum(letter)) do { inFile.get(letter); } while (isalnum(letter) && inFile); } }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

[std::ifstream& inFileという引数自身について]
そのまま.std::ifstream型の参照というだけ.C++のiostreamクラスには自身の状態を表す変数があり,std::basic_iosで定義されている4つの状態のいずれかひとつになる(xxx_bitがたつ).
open / read / write / createなどがエラーや例外捕捉なく完了するとgood状態に移行する.
エラーが原因だとfail状態に,ディスク読み取り中にディスクがなくなるなどのハードウェア的失敗に代表される致命的なエラーだとbad状態になる.
ファイルの終わりに達するとeof状態になる.
operator>>などもreturn std::ifstream&してる.
参照型を渡すのは,こうした状態を更新するため.
またifs >> x >> y; みたいなことしたいから,operator>>はreturnしている.
((ifs >> x) >> y); こういう二項演算になる.

[関数について]
部分的解説

C++

1 if (skip) { 2 inFile.get(letter); 3 while (!isalnum(letter) && inFile) 4 inFile.get(letter); 5 }

inFile.get(letter)
inFileから一文字を読み取り,その整数値を返す.ファイル終端に達した場合はEOFマクロ定義値を返す.
while( !isalunum(letter) && inFile )
letterが半角英数字でない かつ inFileの内部状態がgoodならば

C++

1if (!inFile || !isalnum(letter)) 2 letter[0] = '\0';

inFileの状態がbad or fail または letterが半角英数字でないならば,letterは無効

C++

1do { 2 letters[count] = letter; 3 count++; 4 inFile.get(letter); 5} while (isalnum(letter) && inFile && (count < MAX_CHARS));

while( isalnum( letter ) && inFile && (count < MAX_CHARS) )
letterが半角英数字 かつ inFileの状態がgood かつ インデックスが有効範囲内

全体の解説
1.if文:skip
まずinFileから一文字を読み取る.その結果をもとに半角英数字かどうかを判定しつつ,入力ファイルへのストリームが有効ならば,半角英数字でない文字はただ読み取るだけで読み取り結果は格納せず捨てる.
半角英数字が最初に表れたファイルシークの位置から次のif文へ.
もしskipがoffなら,ただ単に最初の一文字を読み取り,その後の処理のために活用.

2.if文:!isalnum( letter ) || !inFile
inFileのエラーチェックおよび,letterの文字種判定を行う.結果,いずれかがおかしいならlettersを無効にし,この関数の処理は終了.
結果,inFileがgood かつ letterが半角英数字なら,ここで初めてlettersにletterの値を格納,さらにinFileから一文字ずつの読み取りを進める.この処理をletterが半角英数字かつinFileがgoodかつcountが有効範囲内 - 1ならつづける.- 1なのは終端文字を入れるため.
ループから抜けたところで,最後に終端を入れる.そのあと,もしcountがMAX_CHARSなのに,ループの最後で一個余分に読み取ったletterが半角英数ならこのinFileを以後,半角英数字が出現する間はずっと空読みして,この関数の処理を終了(どうでもいいですがこれ無駄じゃないですか?いちどGetしたら,Getしたシーク位置から連続するファイルの中身の半角英数字を,シーク内から外したいのかな・・・).

でもこのMAX_CHARSって大丈夫なのか?count = MAX_CHARSになるけど,そこでletters[count] = '\0'って添え字はみ出してそうだけど・・・

「数字とアルファベットではなかった時点で本来の目的は達成されてないからもう一度読み込むのは無駄ではないのか」
ちゃんとそのあとの処理はスキップしてますよ.elseだったときにのみ,格納しながら読み込みに入ります.
そのあとの後処理もelse文内です.

投稿2015/10/28 23:13

編集2015/10/28 23:21
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問