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

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

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

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

ファイルI/O

ファイルI/Oは、コンピューターにおけるファイルの入出力です。これは生成/削除やファイルを読み込んだり、出力をファイルに書き込むようなディレクトリやファイルの運用を含みます。

Q&A

解決済

1回答

2216閲覧

【C++】プログラムの実行中に参照しているファイルが上書きされてもコンソールに反映されない

_____________

総合スコア8

Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

ファイルI/O

ファイルI/Oは、コンピューターにおけるファイルの入出力です。これは生成/削除やファイルを読み込んだり、出力をファイルに書き込むようなディレクトリやファイルの運用を含みます。

0グッド

0クリップ

投稿2020/04/17 06:23

編集2020/04/17 06:24

前提・実現したいこと

C++で、fstreamのgetline関数を用いて、ファイルの内容を読みとりたい。
※fstreamやgetline以外にぴったりな関数があるようでしたらそちらでも構いません。
※プログラム実行中に、参照しているファイルが編集されるようになっているため、一定時間ごとにループでgetlineを実行します。

発生している問題・エラーメッセージ

プログラムの実行中に参照されているファイルを編集しても、コンソールに反映されない

該当のソースコード

C++

1#include<stdio.h> 2#include<Windows.h> 3#include<string> 4#include<fstream> 5#include<iostream> 6#include<stdlib.h> 7 8 9int main() { 10 std::ifstream ifs("stock_prices.txt"); 11 if (ifs.fail()) { 12 printf("fail"); 13 return -1; 14 } 15 std::string reading, message, news = ""; 16 long long p1 = 0; 17 long long p2 = 0; 18 long long p3 = 0; 19 long long p4 = 0; 20 long long p5 = 0; 21 long long p6 = 0; 22 long long p7 = 0; 23 long long p8 = 0; 24 int i = 0; 25 long long loop_count = 0; 26 while (1) { 27 i = 0; 28 loop_count = loop_count + 1; 29 while (1) { 30 getline(ifs, reading); 31 i++; 32 p1, p2, p3, p4, p5, p6, p7, p8 = -1; 33 if (i == 1) { 34 if (reading != "DATA_STOCK-PRICES") { 35 message = ""; 36 break; 37 } 38 } 39 if (i == 2) { 40 p1 = strtoll(reading.c_str(), nullptr, 10); 41 } 42 if (i == 3) { 43 p2 = strtoll(reading.c_str(), nullptr, 10); 44 } 45 if (i == 4) { 46 p3 = strtoll(reading.c_str(), nullptr, 10); 47 } 48 if (i == 5) { 49 p4 = strtoll(reading.c_str(), nullptr, 10); 50 } 51 if (i == 6) { 52 p5 = strtoll(reading.c_str(), nullptr, 10); 53 } 54 if (i == 7) { 55 p6 = strtoll(reading.c_str(), nullptr, 10); 56 } 57 if (i == 8) { 58 p7 = strtoll(reading.c_str(), nullptr, 10); 59 } 60 if (i == 9) { 61 p8 = strtoll(reading.c_str(), nullptr, 10); 62 } 63 if (i == 10) { 64 if (reading != "") { 65 news = reading.c_str(); 66 } 67 } 68 if (i == 11) { 69 break; 70 } 71 } 72 if (i != 11) { 73 break; 74 } 75 if (loop_count != 1) { 76 Sleep(333); 77 } 78 system("cls"); 79~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 80 } 81 if (message != "") { 82 printf("%s", message.c_str()); 83 return -1; 84 } 85}

補足情報

Visual Studio 2019 Communityを使用

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

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

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

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

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

guest

回答1

0

ベストアンサー

whileループの中で、再オープンしましょう。
通常、この手の読み込みは、キャッシュしているので、一度オープンしたら、ファイルが書き換えられても、読み出される内容は変わりません。
(同期させる方法もあったかもですが、? です)

また、書き込みもファイルクローズまたは、フラッシュがされないと、ファイルの内容は更新されません。
こちらもご注意。

なお、バッファサイズを 0にする方法もありますが、これは、パフォーマンスに影響します。

投稿2020/04/17 12:12

pepperleaf

総合スコア6383

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

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

_____________

2020/04/18 01:49

再オープンの関数や使用方法などがわからないのですが、よろしければ再オープンを用いた例を示していただけないでしょうか。
pepperleaf

2020/04/18 02:18

ifs.close(); --> クローズ ifs.open("stock_prices.txt"); --> オープン (この時、最初の std::ifstream ifs は引数無し) これをループの最初と最後にすれば、良いですが、、、 ...... よく見ると、単純ループ。効率が良くないです。もう一つの書き込みプログラムも手を入れられるなら、パイプとかでつなぎたいところです。
dodox86

2020/04/18 02:40

>pepperleafさん whileループの中で再オープンしたら、いわゆるファイルポインタがリセットされてしまうのではないですか。その辺のケアも必要な気がします。
dodox86

2020/04/18 02:47

また、再オープンのタイミングによってはファイルを書く別プログラムと競合するので、アクセス拒否(ACCESS DENY)が発生する可能性もあります。Windowsでは既定で書き込み時に共有不可だったと思うので、共有モードに影響されます。
_____________

2020/04/18 04:13

pepperleafさんの方法でできました。 dodox86さんの競合については、発生したらここにまた質問させて下さい。 ありがとうございました!
_____________

2020/04/18 04:18

変数p8が-1のままコンソールに表示されてしまいます。 再オープン以外はいじっていないのですが...
dodox86

2020/04/18 06:05

先の私のpepperleafさんへの以下のコメントは指摘として誤りでした。 > whileループの中で再オープンしたら、いわゆるファイルポインタがリセットされてしまうのではないですか。その辺のケアも必要な気がします。 コードを見誤っていましたが、もともと何度もファイル先頭から読み出すことを想定したコードのようですね。であればファイルポインタ云々は関係ありませんでした。大変失礼しました。
_____________

2020/04/18 09:31

>dodox86さん そうでしたか!伝え方が悪くてすいません。
pepperleaf

2020/04/18 11:07

dodox86さん、色々とありがとうございます。確かにファイル競合のリスクもあり、本来はパイプとかでつなぐ、あるいは別の方法での同期も考えるものですね。きちんと考えないと難しいところがあるかもしれません。まあ、単なる書き込み時の一瞬の競合なら、エラー検出で、リトライという安易な方法もあるかもしれません。(ただし、プログラムの使用目的による) また、ファイルを更新しているプログラムの挙動もどうなるのか疑問でもあります。 (Unix系だと、別名でファイル作成.. その後、元ファイル削除.. リネームで上書き.. という方法。この場合、競合はしない)
pepperleaf

2020/04/18 12:46

> 変数p8が-1のままコンソールに表示されてしまいます。 多分、そこで読み込みが失敗。 コードを見ると 11行のデータということでしょうか? 11行まとめて読み込み、成功した場合のみ解釈するようにすべきではないかと思います。 11行読み込み --> 単純には 11行の getline で、失敗した場合は、やり直し、、とか。 もっと良い方法がありそうですが、とりあえず。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問