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

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

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

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

Q&A

解決済

4回答

11734閲覧

[C++]指定ディレクトリ内のファイルを全て読み込みたい。

ryo_se

総合スコア68

C++

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

0グッド

0クリップ

投稿2016/10/07 10:21

編集2016/10/11 13:52

お世話になっております。
下記のようなことを実現したくお力を貸していただきたいです。

1.特定ディレクトリ内には名前に日時が記載されたファイルが複数ある
例:Test20161007100551.txt
(数字はyyyyMMddHHMMss形式)

2.特定ディレクトリからファイル名を見て、24時間以内のファイルの中身を全て読み出し、
文字型変数に保存したい。

しかし、一つのファイルパスを指定してファイルの内容を読み出すことはできたのですが、
24時間以内のファイルの判断、ディレクトリから複数ファイルの読みこみが実現できません。

お手数お掛けしますが、ご教示のほどよろしくお願い致します。

@補足1
すみません、情報を記載し忘れました。
OSはXP、visual studio2003を使用しています。
仕様のためかなり古いバージョンです。

@補足2
今回のコーディングにおいては、.NETではなくMFCを使用しております。
今までJAVA屋だったもので、C++についてはわからない点が多く、
詳しく教えていただければ幸いです。

試行錯誤して下記のような流れで実現できました。

1._findfirst、_findnextを使用し、ファイル名を取得
2.ファイル名から時間の文字部分を抽出
3.時間の文字部分をSYSTEMTIME形式に変換
4.SYSTEMTIME変数をCTimeに変更し、現在時刻との差異を取得
5.24時間以内の場合、CFileを使用してファイル名からファイルオープン

ただ一つ気になっている部分が3の部分で下記のようなコードで作りました。

// 2016/10/08 00:00:00 に変換 targetTimeStr = "20161008000000"; setStr = targetTimeStr.Left(4); setStr += "/"; setStr += targetTimeStr.Mid(4,2); setStr += "/"; setStr += targetTimeStr.Mid(6,2); setStr += " "; setStr += targetTimeStr.Mid(8,2); setStr += ":"; setStr += targetTimeStr.Mid(10,2); setStr += ":"; setStr += targetTimeStr.Mid(12,2);

冗長的な感じなのですがもう少しうまい方法はありますでしょうか?
JavaであればFormat変数等で対応できるのですが・・

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

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

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

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

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

guest

回答4

0

XPであればFindFirstFileAとFindNextFileA(どちらもWin32 API)でファイル情報(名前、日付など)が取得できます。詳しい使い方は、ファイルの列挙などを参考にしてください。

投稿2016/10/07 11:46

cateye

総合スコア6851

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

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

0

ベストアンサー

MFCであれば他の方も回答していますがCFileFindクラスでファイルの列挙が出来ます。(ワイルドカードが使えます)http://www.g-ishihara.com/mfc_fi_03.htm

日時はファイル名で判断ということなので、ファイル検索で見つかったファイル名を年、月、日、時、分、秒に分解し、CTimeクラスを使って現在時刻との差分をとれば判断できます。(文字列の数値変換も必要ですがatoi等を使えば出来ます。わからなければ「C++ 文字列 数値変換」でググればたくさんヒットします。)
日時の判断はCTimeとCTimeSpanを参照してください。基本的には差分を取って24時間を超えているかどうかを判断するだけです。

投稿2016/10/11 09:14

PineMatsu

総合スコア3579

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

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

0

24時間以内は更新日時かと思いますので、各OSで更新日時を取得する関数をあげておきます。

  • UNIX(Mac含む)/Linux

stat, fstat, lstat, fstatat

  • Windows (UNIX互換)

_stat、_wstat系
_fstat系

  • Windows (Win32API)

GetFileTime

マルチプラットフォームに書くのであれば、Chironianさんがいうようにboost::filesystemを使うか、

C++

1#ifdef _WIN32 2define stat(p, b) _stat((p), (b)) 3#endif

等と書いて、stat等を使うかでしょうか。


【補足への追記】

Visual Studio .NET 2003であっても、_stat系は使えます。


【コメントへの追記】

ファイル名からであれば文字列を分解して日時(time_t)に変えて比べるぐらいでしょう。ちょっとサンプルを作ってみました。手元にVisual C++ 2003が無いため試していませんが、GCCで-std=c++98にして一応動きましたので、たぶん、うまくいくでしょう。ファイル名のフォーマットチェックとか省いていますので、実際はそこら辺も追加してください。charではなくWCHARで扱いたい場合は、std::wstringとwtoiに変更してください。

C++

1#include <iostream> 2#include <stdlib.h> 3#include <string> 4#include <time.h> 5 6time_t getTimeFromFileName(std::string s); 7 8int main() 9{ 10 // 現在日時 11 time_t now = time(NULL); 12 13 std::string filepath("C:\\Temp\\Test20161007100551.txt"); 14 time_t name_time = getTimeFromFileName(filepath); 15 16 double diff_days = difftime(now, name_time) / (24 * 60 * 60); 17 std::cout << "file: " << filepath << std::endl 18 << "diff time (days): " << diff_days << std::endl; 19 return 0; 20} 21 22time_t getTimeFromFileName(std::string str) 23{ 24 // yyyyMMddHHMMss.txt であることが前提。 25 std::string time_str = str.substr(str.length() - 18, 14); 26 27 struct tm time = {.tm_sec = atoi(time_str.substr(12, 2).c_str()), 28 .tm_min = atoi(time_str.substr(10, 2).c_str()), 29 .tm_hour = atoi(time_str.substr(8, 2).c_str()), 30 .tm_mday = atoi(time_str.substr(6, 2).c_str()), 31 // tm_mon は1月から換算。 32 .tm_mon = atoi(time_str.substr(4, 2).c_str()) - 1, 33 // tm_year は1900年から換算。 34 .tm_year = atoi(time_str.substr(0, 4).c_str()) - 1900, 35 // tm_wday と tm_yday は mktime() で無視される。 36 .tm_wday = 0, 37 .tm_yday = 0, 38 // 夏時間フラグ、日本は夏時間が無いため 0 にする。 39 .tm_isdst = 0}; 40 return mktime(&time); 41}

投稿2016/10/07 11:21

編集2016/10/08 01:23
raccy

総合スコア21735

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

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

ryo_se

2016/10/07 23:27

すみません、時間についてはファイルの更新情報ではなく、あくまでファイル名を見て判断したいです。
guest

0

こんにちは。

標準ライブラリでは実現できませんので、OSのAPIを直接呼ぶか、boostのようなライブラリを使う必要が有ります。
取り敢えずOSが不明なので、boostを使う方法を回答します。boost::filesystemを使えば簡単です。ただ、boostのfilesystemをビルドする必要が有るのでそこはちょっと面倒です。


【質問の補足を見て追記】
MFCはあまり知らないのですが、検索するとMFCにはCFileFindクラスがあり、これを使うと簡単みたいです。
CFileFindを使ったファイル検索にサンプル・ソースがあります。
CFileFind のメンバをみると、GetLastWriteTimeメソッドを使ってFILETIME構造体として更新日時を獲得できるようです。
FILETIME構造体を使ってCTimeをコンストラクトすれば、現在時刻との差分も簡単に計算できそうです。

投稿2016/10/07 10:29

編集2016/10/08 02:20
Chironian

総合スコア23272

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問