回答するまえに以前の質問トピックにて解決した際のソース投稿をお願いします。
(解決しましただけではどのように解決したのかわかりませんので)
viewtopic.php?f=3&t=20804
あや さんが書きました: ↑4年前
以下が入力テキストです.
NASA debuted a color picture from the Spirit rover
on Tuesday showing gray rocks peppering a Martian
lake bed awash in its natural hues of red pink
and orange Mission scientists said they were
bowled over by the spectacular quality of
the image taken with a dual camera system
called pancam that is mounted on a mast jutting
up from the rover I think my reaction has been
one of shock and awe said Jim Bell the team
member in charge of pancam Using special software
mission scientists can fly though the image zooming
in on rocks and other landscape features of interest
It is approximately the color that you would see
with your eyes if you were standing there Bell said
The resolution of course is pretty much what you
would see Pancam has 20 20 vision It is three to
four times better than any previous mission that has gone
to Mars in fact these pictures are the highest resolution
highest detailed pictures of Mars ever obtained They
are absolutely spectacular
単語数:173と出力したいのですが,単語数:0と出力されてしまいます.
main関数のchの値をupdateWord関数内でも参照するにはどうすればいいのか,具体的に教えて下さい.よろしくお願いします.
入力テキストの中身と期待する結果および実際の出力についてご提示いただきありがとうございます。
ただ、私の先の回答ではそれ以外にも確認してほしい内容を提示していますのでそちらの確認もお願いできればと思います。
(それとも、プログラムの動作原理や問題点の洗い出し、それを受けてどうすればよいのかを考えるのはどうでもよくて、体よく答え(あるいは答えに直結する問題点の提示)だけを求めていますか?)
・各変数に入っている値の確認(ステップ実行でも各処理での変数値を標準出力する方法でも構いません)
・関数と変数のスコープの関係を理解しているか?
・main関数内のchとupdateWord関数内のchが同じものであると確認できたか?
あやさんがどこまで知識があるのかわかりませんので参考までに文字読み出し部分と
単語数のカウント関数であるupdateWord関数内でのchについてアドレスと保持している値を出力するように
追記してみました。
コード:
#include <string>
#include <fstream>
#include <iostream>
using namespace std;
// 定数定義
#define B 0 // 空白文字
#define N 1 // 通常文字
// プロトタイプ宣言
void updateWord(void); // 単語数を更新する
// 大域変数
int word; // 単語数
int type; // 直前入力文字の種別
/********************************
メイン関数
********************************/
int main() {
ifstream file; // 入力ファイル
char ch; // 入力文字
int letter; // 文字数
int line; // 行数
// 1. 文字数、単語数、行数を0とする。
letter = 0;
word = 0;
line = 0;
// 2. 「直前入力文字の種別」を「空白文字」とする。
type = B;
// 3. ファイルを開く。
file.open("test.txt");
// 4. ファイルから1文字読み込む。
ch = file.get();
// 5. ファイルの未尾に到達するまで以下の処理を繰り返す。
while (!file.eof()) {
// 5-1. 文字数を1増やす。
letter++;
// 5-2. 単語数を更新する。
cout << "func main ch(" << hex << reinterpret_cast<void *>(&ch) << "): " << ch << endl; // main関数でのch出力
cout << "func main type(" << hex << reinterpret_cast<void *>(&type) << "): " << type << endl; // main関数でのtype出力
updateWord();
// 5-3. 読み込んだ文字が改行文字ならば、行数を1増やす。
if (ch == '\n') {
line++;
}
// 5-4. ファイルから1文字読み込む。
ch = file.get();
}
// 6. 入力ファイルを閉じる。
file.close();
// 7. 文字数、単語数、行数を出力する。
cout << "文字数:" << letter << endl;
cout << "単語数:" << word << endl;
cout << "行数:" << line << endl;
}
/********************************************
単語数を更新する
********************************************/
void updateWord(void) {
char ch=0; // 入力文字
// 1. 読み込んだ文字が空白文字ならば、以下の処理を行う。
cout << "func updateWord ch(" << hex << reinterpret_cast<void *>(&ch) << "): " << ch << endl; // updateWord関数でのch出力
cout << "func updateWord type(" << hex << reinterpret_cast<void *>(&type) << "): " << type << endl; // updateWord関数でのtype出力
if (isspace(ch)) {
// 1-1. 「直前入力文字の種別」が「通常文字」ならば、単語数を1増やす。
if (type == N) {
word++;
// 1-2. 「直前入力文字の種別」を「空白文字」とする。
type = B;
}
// 2. そうでない場合、以下の処理を行う。
else {
// 2-1. 「直前入力文字の種別」を「通常文字」とする。
type = N;
}
}
}
実行してみると以下のような結果が出力されるかと思います。
(0x~の部分は値が異なっていると思いますがそれでOKです。)
コード:
func main ch(0x7ffdaaf5663e): N
func main type(0x6021dc): 0
func updateWord ch(0x7ffdaaf56616):
func updateWord type(0x6021dc): 0
func main ch(0x7ffdaaf5663e): A
func main type(0x6021dc): 0
func updateWord ch(0x7ffdaaf56616):
func updateWord type(0x6021dc): 0
func main ch(0x7ffdaaf5663e): S
func main type(0x6021dc): 0
func updateWord ch(0x7ffdaaf56616):
func updateWord type(0x6021dc): 0
func main ch(0x7ffdaaf5663e): A
func main type(0x6021dc): 0
func updateWord ch(0x7ffdaaf56616):
func updateWord type(0x6021dc): 0
func main ch(0x7ffdaaf5663e):
func main type(0x6021dc): 0
func updateWord ch(0x7ffdaaf56616):
func updateWord type(0x6021dc): 0
(以下略)
上記の出力はテキストファイルから1文字読み取るごとにmain関数とupdateWord関数での
読み取り文字を格納している変数chと文字種別を判定した結果を格納している変数typeの出力です。
main関数でのchだけを抜き出してみると、
コード:
func main ch(0x7ffdaaf5663e): N
func main ch(0x7ffdaaf5663e): A
func main ch(0x7ffdaaf5663e): S
func main ch(0x7ffdaaf5663e): A
func main ch(0x7ffdaaf5663e):
(以下略)
と期待した通りNASA …と1文字ずつ取得されている様子がわかりますよね。
それに対し、単語数カウントを行うupdateWord関数でのchだけを抜き出してみると、
コード:
func updateWord ch(0x7ffdaaf56616):
func updateWord ch(0x7ffdaaf56616):
func updateWord ch(0x7ffdaaf56616):
func updateWord ch(0x7ffdaaf56616):
func updateWord ch(0x7ffdaaf56616):
(以下略)
とmain関数で取得できていた値が取れていないことがわかります。
なんで同じchを参照しているはずなのに?と思われるかと思いますが、
その秘密は()内の値にあります。
main関数の方は「0x7ffdaaf5663e」、updateWord関数の方は「0x7ffdaaf56616」となっていますが、
これは変数の値が格納されている場所(アドレス)です。
これが一致していないということは変数の名前は同じでも実際に見ている先は全然別の場所を見ているということになります。
一方、直前の文字種別を保存している変数typeの方は、
コード:
func main type(0x6021dc): 0
func updateWord type(0x6021dc): 0
func main type(0x6021dc): 0
func updateWord type(0x6021dc): 0
func main type(0x6021dc): 0
func updateWord type(0x6021dc): 0
func main type(0x6021dc): 0
func updateWord type(0x6021dc): 0
func main type(0x6021dc): 0
func updateWord type(0x6021dc): 0
(以下略)
のようにmain関数でもupdateWord関数内でも共に「0x6021dc」となっています。
これはなぜかというと変数を宣言している場所の違いによります。
プログラムを見てもらうと変数typeは大域変数としてmain関数の外で宣言されています。
一方変数chはmain関数内とupdateWord関数内でそれぞれ宣言されています。
変数は宣言されたブロック内でしか有効にならないので、main関数内で宣言された変数chは
updateWord関数内では無効になってしまいます。
updateWord関数内でも変数chは宣言されていますが、main関数内の変数chとは別のものとして扱われます。
このあたりの挙動は大域変数と変数のスコープの関係によるものですが、そのあたりはご理解いただけているのでしょうか?
長文になってしまったのでいったんここまでの回答にしますが、変数chを変数typeと同じように大域変数として定義すればmain関数からでもupdateWord関数内からでも参照できる変数になるので、
updateWord関数内でテキストファイルから読み取った文字を参照することは可能になるかと思います。
それ以外にも問題はありますが上記を修正したら再度実行してもらい、変数の値と処理の流れが各所で期待している通りかを確認してもらえればと思います。