プロが教える店舗&オフィスのセキュリティ対策術

hogehoge_1_1_1.txt
hogehoge_1_2_3.txt

というファイル名であった場合、
hogehoge_1_1_1.txtからは1 1 1
hogehode_1_2_3.txtからは1 2 3
というふうにファイル名の他に数値もテキストファイルに出力したい場合どのようにすればできるでしょうか?

このように単純な作業なのですが、
このような形式のテキストファイルが大量にあって、まとめて処理してグラフなんかを作成したいために質問させていただきました。

回答よろしくお願いします。

補足
説明が不足していましたが、実行ファイルと同じフォルダに入れたテキストファイル等すべてから、ファイル名を指定しないで数値の部分だけを取り出すようにするにはどうしたらいいかも知りたいです。

分かりにくい説明かもしれませんが、回答よろしくお願いします。

A 回答 (5件)

C++でのコード例はだれか書いてくれるでしょうから、別案のアドバイス。



> hogehoge_1_1_1.txtからは1 1 1
> hogehode_1_2_3.txtからは1 2 3

Cのコードを書くまでもなく、シェルスクリプトとかで、抽出したほうが手っ取り早いと思います。
たとえば、Windowsのコマンドプロンプトからなら、こんな感じ:

@for /F "usebackq delims=_. tokens=2,3,4" %d in (`dir /b hoge*`) do @echo %d %e %f
「c++でファイル名から数字をテキストファ」の回答画像1

この回答への補足

分かりやすい回答ありがとうございます。
もしもで、できればでんすが、このコマンドの単語の意味を教えていただくことはできないでしょうか?
コマンドプロンプトをあまり使ったことがないもので。

もしできれば、外にテキストファイルのような形で出力したい場合はどうすればいいのでしょうか?

質問を繰り返してしまいすいません。

補足日時:2011/01/23 09:39
    • good
    • 0

Cなら opendirでディレクトリを開いて


readdirで1エントリーずつ読みこんで、
ファイル名を確認して、sscanfあたりで数値を抜き出して
...
ってなるでしょうね。



ちなみに、私なら
Cのプログラムではコマンドライン引数でファイル名を渡すようにして、ファイル展開はシェルやコマンドプロンプトに任せる
とか、
全部シェルスクリプトやPerlとかで書く
とかしますね。
こんなところに時間かけるくらいなら、肝心の計算部分に注力したいので。

この回答への補足

なぜ、C++のプログラムでという形で質問したかというと、c++のプログラムですでに、実験の数値の並んだファイルの平均とその分散を取り出すプログラムを持っているんですが、ファイル名の情報を取り出す作業がそれではできないものなんです。

だから、そのソースコードを書きなおして、上で言うような機能を付けてやろうと思っていたところだったんです。

説明が十分でなくてすいませんでした。

補足日時:2011/01/23 09:44
    • good
    • 0

#include <iostream>


#include <sstream>
#include <string>
#include <algorithm>

using namespace std;

int main() {
string input = "hogehoge_1_23_456.txt";
replace_if(input.begin(),input.end(),[](char ch) { return ch < '0' || ch > '9';},' ');
istringstream stream(input);
int result;
while ( stream >> result ) cout << result << endl;
}
    • good
    • 0

他の回答者さんと同じく、僕もこういう仕事はあまりC/C++向きではないと思います。


Windowsだったらコマンド プロンプトやPowerShell、UNIXだったらシェル、クロスプラットフォームだったらPerlなどのスクリプト言語を使ったほうが楽です。
特にファイルまわりはOSの機能を利用しないといけないので、C/C++であれば直接APIを呼ばないと返って面倒になります。環境依存しないコードを書こうと思ったら、boost::filesystemのようなラッパーを使わないといけないし……
僕だったら下記のようなPythonコードを使って、出力結果をログファイルにリダイレクトします。

import glob, re
flist = glob.glob('*.txt')
for fname in flist:
 m = re.search('hogehoge_(\d)_(\d)_(\d)\.txt', fname)
 print fname + ' ' + m.group(1) + ' ' + m.group(2) + ' ' + m.group(3)

(インデントの全角スペースはタブか半角スペースに置換する必要があります。Windows 7 x64, IronPython 2.6.2 でテストしています)
    • good
    • 0

(「c++で」とあるのに・・・、どっぷりCで申し訳ない)



>ファイル名を指定しないで数値の部分だけを取り出す・・

 ・ファイルを探す。
 ・ファイル名中の数字列を、atoi で数値化する。

 で、できると思います。
 なお、C標準関数だけではフォルダからファイルを検索する方法はありません。

 下の例は、C++Builder 5. の場合です。
 他の環境でも、関数などが用意されていると思いますので、環境依存部分(◆)を変更し、試して下さい。

 ( return( 1 ); は、「サクラエディタ」の「外部コマンド実行 → 表示」用のもので他意はありません)

#include <dir.h> // ◆ VC++ なら io.h ?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define N_CNT 3 // ファイル名に含まれる数値の数
#define DLMT '_' // 数値と数値の区切り文字

int main()
{
 int iVal, iDone, iCnt;
 char *p;
 struct ffblk sInfo; // ◆構造体名

 iDone = findfirst( "Z:/temp/*.*", &sInfo, FA_NORMAL ); // ◆関数名、引数

 while( ! iDone ){

  printf( "%s", sInfo.ff_name ); // ◆構造体メンバ名

  p = sInfo.ff_name; // ◆ 〃

  iCnt = 0;

  while( iCnt < N_CNT ){

   p = strchr( p, DLMT );

   if( NULL != p ){

    iCnt++;

    p++;

    iVal = atoi( p ); // 「数値の部分だけを取り出す」

    printf( "\t[%d] %d", iCnt, iVal );
   }
   else break;
  }
  printf( "\n" );

  iDone = findnext( &sInfo ); // ◆構造体名、引数
 }
 return( 1 );
}
注:インデントに全角空白を用いています。コピペ後、タブに一括変換して下さい。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!