ファイル名リストの置換処理

このQ&Aのポイント
  • 取得したファイルリストを文字列で入れ替える方法について
  • ファイルリストの中で最初の位置の文字列を特定の名前で置き換える方法
  • ファイル名リストの取得と置換処理に関する実装例
回答を見る
  • ベストアンサー

ファイル名リストの置換処理

以前、ファイルリストの取得について教えて頂きました。ありがとうございます。 取得したリストを文字列で入れ替えるにはどうすればよいでしょうか 例えば取得したリストの最初の位置の文字列dml[0]をEcoDataFileNameと置き換えたいです。 #include <Windows.h> #include <map> #include <vector> #include <string> #include <iostream> #include "time.h" using namespace std; bool operator<(const FILETIME& x, const FILETIME& y) { if ( x.dwHighDateTime < y.dwHighDateTime ) return true; if ( y.dwHighDateTime < x.dwHighDateTime ) return false; return x.dwLowDateTime < y.dwLowDateTime; } class DML_Backup { vector<string> files_; public: void search(const char* spec) { typedef multimap<FILETIME,string> map_type; map_type files; WIN32_FIND_DATAA find_data; HANDLE handle = FindFirstFileA(spec, &find_data); if ( handle != INVALID_HANDLE_VALUE) { do {   files.insert(map_type::value_type(find_data.ftLastWriteTime, find_data.cFileName)); } while ( FindNextFileA( handle, &find_data) ); FindClose(handle); } files_.clear(); for ( map_type::iterator iter = files.begin(); iter != files.end(); ++iter ) { files_.push_back(iter->second); } } string operator[](int inx) const { return files_.at(inx).c_str(); } int size() const { return files_.size(); } }; int main() { DML_Backup dml; char EcoDataFileName="MonJun131956122011.ecd"; dml.search("*.ecd"); }

質問者が選んだベストアンサー

  • ベストアンサー
  • hitomura
  • ベストアンサー率48% (325/664)
回答No.5

なんか仕様が増えたーー!? > 実はファイル自体存在させる個数が決まっており、ファイルのリストを一度作成した場合、後はリストに新規作成したファイルを追加するようにしたかったのです。 > ですから、10個のリストになった場合にサイクリックに、今度は先頭から上書きして、古いファイルから消していくような仕様でした。 > その際実際存在する古いファイルも消すという内容です。 そういう仕様であるならば、なおさらファイル名の「上書き」メソッドは実装すべきではありません。そもそもファイル名の並びは最終更新日時の古い順のはずです。それを外部から書き換え可能にしてしまったら順番がばらばらになってしまいます。 実装すべきはファイルリストへの追加処理でしょう。とりあえず以下にファイル名のみ追加するものを書きましたが、クラスの役目を考慮して、この処理の中で実ファイルの作成・削除も行うというてもあります。 void DML_Backup::add(const string& filename) {  files_.push_back(filename);  int erasing_files = files_.size() - 10;  if (0 < erasing_files){   files_.erase(files_.begin(), files_.begin() + erasing_files);  } } ……でも、これだったらコンテナはvectorよりもlist(ただしoperator[]の書き換えが必要)やdequeのほうがいいような気がしますが。

その他の回答 (4)

  • hitomura
  • ベストアンサー率48% (325/664)
回答No.4

> これは例えば日付が古い順にソートした場合、リストの個数に上限があり、上限に達した場合、リストの先頭に戻り、順番に新しいファイルを上書きして行くという処理です。 何かおかしいと思ったら、そういうことですか。 このDML_Backupクラスの場合、外部からファイル名を書き換えるメソッドは不要です。というか、作ってはいけません。 なぜならば、このクラスで保持しているファイル名はsearchメソッドで検索したものであり、ディスク等にあるファイルという実体があります。外部からファイル名を書き換えると、その実体からクラス内のデータを乖離させることになります。 したがって、そのメソッドで元の名前のファイルを新しいファイル名に変更する処理を同時に行うのでない限り、外部からファイル名を書き換えるメソッドを作るべきではありません。 「リストの個数に上限があり」云々という制限はデータを表示する側の都合であり、データを表示する側で対処すべきです。たとえば以下(逐次処理を行って進捗をリストに表示する)のように処理を行うファイルのインデックスをリストの表示可能行数で割った余りでファイル名を書く行が求められます。 const int ListLines = 10; // リストの表示可能行数 int main() { DML_Backup dml; dml.search("*.ecd"); for (int i = 0; i < dml.size(); i++){  int disp_line = i % ListLines;  // リストの disp_line 行に dml[i] を書く  // ファイル dml[i] に対して処理実行 } }

babel05177
質問者

補足

ありがとうございます、実はファイル自体存在させる個数が決まっており、ファイルのリストを一度作成した場合、後はリストに新規作成したファイルを追加するようにしたかったのです。ですから、10個のリストになった場合にサイクリックに、今度は先頭から上書きして、古いファイルから消していくような仕様でした。その際実際存在する古いファイルも消すという内容です。そのような理由で質問をさせて頂いておりました。

回答No.3

> string operator[](int inx) const { return files_.at(inx).c_str(); } コレ↑を書き換え: string operator[](int inx) const { return files_.at(inx); } string& operator[](int inx) { return files_.at(inx); } ってするだけでよくね? # 教本買って「ちゃんと」勉強することを強くお勧めします。

  • hitomura
  • ベストアンサー率48% (325/664)
回答No.2

質問とは直接関係ありませんが、  string operator[](int inx) const { return files_.at(inx).c_str(); } は c_str() が余計で、  string operator[](int inx) const { return files_.at(inx); } で十分です。

回答No.1

void DML_Backup::replace( const char* pstr ) {   vector<string>::iterator it = files_.begin();   if( files_.end() != it )   {     *it = pstr;   } } int main() {   DML_Backup dml;   char EcoDataFileName[]="MonJun131956122011.ecd";   // 先頭のstringを置き換える   dml.replace(EcoDataFileName); }

babel05177
質問者

補足

ありがとうございます。では先頭から適宜、順番に任意の文字列に差し替えるにはどうすれば良いでしょうか?これは例えば日付が古い順にソートした場合、リストの個数に上限があり、上限に達した場合、リストの先頭に戻り、順番に新しいファイルを上書きして行くという処理です。わかりにくくてすみません。

関連するQ&A

  • 新しい順のリスト取得

    この件につきましては、特定の回答者の方のおかげで収束につながりました。あとひとつだけお力をください。ファイルの古い順にリストを作成してもらいましたが、これに新しい順にソートする機能を追加したいです。これで仕様としては終わりです。どうかよろしくお願いいたします bool operator<(const FILETIME& x, const FILETIME& y) { if ( x.dwHighDateTime < y.dwHighDateTime ) return true; if ( y.dwHighDateTime < x.dwHighDateTime ) return false; return x.dwLowDateTime < y.dwLowDateTime; } class DML_Backup { public: vector<string> files_; void search(const char* spec) { typedef multimap<FILETIME,string> map_type; map_type files; WIN32_FIND_DATAA find_data; HANDLE handle = FindFirstFileA(spec, &find_data); if ( handle != INVALID_HANDLE_VALUE) { do { files.insert(map_type::value_type(find_data.ftLastWriteTime, find_data.cFileName)); } while ( FindNextFileA( handle, &find_data) ); FindClose(handle); } files_.clear(); for ( map_type::iterator iter = files.begin(); iter != files.end(); ++iter ) { files_.push_back(iter->second);         } }

  • 文字列のコピー

    ecoFileListに文字列をコピーしたいのですが、エラーになります。 どなたか教えて下さい int DML_Backup::searchEcoDataFileName(char (*ecoFileList)[32]) { map_type files; WIN32_FIND_DATA find_data; HANDLE handle = FindFirstFile("*.ecd", &find_data); if ( handle != INVALID_HANDLE_VALUE) { do { files.insert(map_type::value_type( find_data.ftLastWriteTime, find_data.cFileName)); } while ( FindNextFile( handle, &find_data) ); FindClose(handle); } for ( map_type::iterator iter = files.begin(); iter != files.end(); ++iter ) { lstrcpy(*ecoFileList, iter->second); ecoFileList++; } }

  • ファイル名のリスト取得について2

    windowsで任意のフォルダにあるファイル名のリストを取得する方法を教えて頂きました。 ※例えば*.ecdのファイルリストを取得する場合です。 これを作成された日付が古い順に取得する事は出来ますでしょうか #include <windows.h> #include <stdio.h> int main() { WIN32_FIND_DATA ffd; HANDLE h = FindFirstFile("d:\\work\\*.ecd", &ffd); if ( h != INVALID_HANDLE_VALUE ) { do { puts(ffd.cFileName); } while ( FindNextFile(h, &ffd) ); FindClose(h); } }

  • str メンバ関数について

    str メンバ関数について 下記のstring Date::to_string() const のstr()メンバ関数が日付クラスDate、 (インタフエース部、実装部)に定義等が記入されていないので、何処に定義されているか教えてください。 ************************************************************* // 日付クラスDate(第2版:実装部) #include <ctime> #include <sstream> #include <iostream> #include "Date.h" using namespace std; //--- 文字列表現を返却 ---// string Date::to_string() const { ostringstream s; s << year << "年" << month << "月" << day << "日"; return s.str(); } ****************************************************************** // 日付クラスDate(第2版:インタフェース部) #include <string> #include <iostream> using namespace std; class Date { int year; // 西暦年 int month; // 月 int day; // 日 public: Date(); // デフォルトコンストラクタ Date(int y, int m = 1, int d = 1); // コンストラクタ int Year() const { return year; } // 年を返却 int Month() const { return month; } // 月を返却 int Day() const { return day; } // 日を返却 string to_string() const; // 文字列表現を返却 }; ostream& operator<<(ostream& s, const Date& x); // 挿入子

  • C++ の map についてです

    C++の初心者です。よろしくお願いします。 DirectXを使っていて簡単なゲームを作っていまして、 mapを使っていると、このようなエラーが出てしまいどうしても理由わかりませんでした。 class D2DMap : public GameTexture{ protected: GameTexture** CopyTexture; int MaxMass; int WidthMass; int HeightMass; int WidthMassPixel; int HeightMassPixel; int MassInfo[30][30]; public: D2DMap(); virtual ~D2DMap(); HRESULT LoadMapTexture(int widthmass, int widthmasspixel,int heightmass, int heightmasspixel, const char* FileName, D3DCOLOR color); HRESULT LoadTextMass(const char* FileName); int GetWidthMassPixel(){ return WidthMassPixel;} int GetWidthMassNum(){ return WidthMass;} int GetHeightMassPixel(){ return HeightMassPixel;} int GetHeightMassNum(){ return HeightMass;} int GetMassInfo(int x, int y){ return MassInfo[y][x];} void DrawMap(D3DCOLOR color); void DrawCopyMap(D3DCOLOR color); void SetCopyTex(GameTexture* copy){ CopyTexture= &copy;} void Delete(){} }; map<string , D2DMap*> MapBox; と定義して string Name="--------"; D2DMap map; MapBox.insert( map<string, D2DMap*>::value_type(Name, &map)); としたとこと error C2275: 'std::string' : この型は演算子として使用できません 'std::string' の宣言を確認してください。 error C2059: 構文エラー : '>' error C2039: 'value_type' : '`global namespace'' のメンバではありません というエラーが出てきました。 mapのfind や iterator は可能なのですがinsertの場合エラー となり、理由が全く分かりません。詳しい方アドバイスをお願いしたい のですが、よろしくお願いします。 VC++2008 を使っています。

  • 関数名、パラメータは同じで、戻り値によって異なる処理?

    戻り値というより、受け側によって関数の振る舞いを変えたいのですが、 C++では、同名、同パラメータはC2556のコンパイルエラーになります。 Perlでいうリスト値を返すかスカラー値を返すかは呼び出し側によるようなことをしたいのですが、C++では無理でしょうか? 下の例では、//...部分は戻り値によって異なるのでC++のテンプレート?では無理そうですが、そんなことはC++でできるのでしょうか? 似たようなテクニックでも構いませんので、知識の豊富な方、教えてください。 #include <iostream> #include <string> using namespace std; class A { public: A(){} ~A(){} int test(int x, int y){           //... return 0; } string test(int x, int y){ // ... return ""; } }; void main(void){ A a; int ret1 = a.test(1,2); string ret2 = a.test(1,2); cout << endl << "End..." << endl; }

  • c言語の問題です。ファイルからデータを読み込み連結リストに記憶しソートするプログラムです。お願いします

    ソート部分がどうしてもできません。 またソートは以下のアルゴリズムで行うものです 与えられたリストをリストA、ソート済みのリストをリストBとする。処理の開始段階では、リストBは空である。 1.リストAの要素の中で、最大値をもつ要素Cを探す。 2.要素CをリストAから削除する。 3.要素CをリストBの先頭に挿入する。 4.リストAが空であれば終了。空でなければ 1. にもどる。 #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct physical Physical; struct physical { char name[41]; int age; float height; float weight; Physical *next; }; void read_data(char *file,Physical *p,Physical *tail); int comp1(const Physical *, const Physical *); int comp2(const Physical *, const Physical *); int comp3(const Physical *, const Physical *); int comp4(const Physical *, const Physical *); void sort(char *arg,Physical *p,Physical *q); Physical *listsort(Physical *p, int (*compar)(const void *, const void *)); int main(void) { char s[20],t,u[20]; Physical *p,*tail,*q; p=malloc(sizeof(Physical)); q=malloc(sizeof(Physical)); tail=malloc(sizeof(Physical)); while(1) { printf("CMD>"); fflush(stdout); fgets(s,20,stdin); sscanf(s,"%c %s",&t,u); switch(t){ case 'q':exit(0); case 'r':read_data(u,p,tail); break; case 's':sort(u,p,q); break; case 'd': while(q!=NULL) { printf("%s %d %.1f %.1f ",q->name,q->age,q->height,q->weight ); q=q->next;} break; } } free(p); return 0; } void read_data(char *file,Physical *p,Physical *tail){ FILE *fp; char string[100]; Physical header; tail=&header; header.next = NULL; p->next = NULL; tail->next = p; tail = p; if ((fp = fopen(file, "r")) == NULL) { exit(1); } while(fgets(string,sizeof(string),fp)!= NULL) { sscanf(string,"%s %d %f %f",p->name,&p->age,&p->height,&p->weight); Physical *tail2; tail2=malloc(sizeof(Physical)); tail2->next=NULL; p->next=tail2; p=tail2; } fclose(fp); } void sort(char *arg,Physical *p,Physical *q){ if(strcmp(arg,"name") == 0) q=listsort(p,(int(*)(const void*, const void*))comp1); if(strcmp(arg,"age") == 0) q=listsort(p,(int(*)(const void*, const void*))comp2); if(strcmp(arg,"height") == 0) q=listsort(p,(int(*)(const void*, const void*))comp3); if(strcmp(arg,"weight") == 0) q=listsort(p,(int(*)(const void*, const void*))comp4); } Physical *listsort(Physical *p,int (*compar)(const void *, const void *)){ Physical *q, *max,*s,*head; s=malloc(sizeof(Physical)); head=malloc(sizeof(Physical)); head=NULL; while(p->next){max = p, q = p->next; while( q->next ) { if( compar(q->next,max->next) ) max = q; q = q->next;} s=max->next; max->next=max->next->next; if(head==NULL) {head=s;} s->next=s; } return head; } int comp1(const Physical *a, const Physical *b){ return (strncmp(a->name,b->name,sizeof(Physical))); } int comp2(const Physical *a, const Physical *b){ if(a->age > b->age) return 1; else return 0; } int comp3(const Physical *a, const Physical *b){ if(a->height > b->height) return 1; else return 0; } int comp4(const Physical *a, const Physical *b){ if(a->weight > b->weight) return 1; else return 0; }

  • HANDLEて何ですか?

    #include <windows.h> #include <stdio.h> #include <conio.h> int Locate(HANDLE, int, int); int TxtPrint(HANDLE, char *); int main() { HANDLE hStdout; SYSTEMTIME st; char str[32]; hStdout = GetStdHandle(STD_OUTPUT_HANDLE); while(!_kbhit()) { Locate(hStdout, 0, 10); GetLocalTime(&st); wsprintf(str, "現在%2d時%2d分%2d秒です", st.wHour, st.wMinute, st.wSecond); TxtPrint(hStdout, str); Sleep(500); } return 0; } int Locate(HANDLE hOut, int x, int y) { COORD dwPos; dwPos.X = (SHORT)x; dwPos.Y = (SHORT)y; if (SetConsoleCursorPosition(hOut, dwPos) == 0) return -1; else return 0; } int TxtPrint(HANDLE hOut, char *str) { BOOL bResult; DWORD dwResult; bResult = WriteConsole(hOut, (CONST VOID *)str, (DWORD)lstrlen(str), &dwResult, NULL); if (bResult == 0) return -1; else return 0; } よくハンドルと言う言葉が出てくるのですが、いまいち意味がわかりません。あとint Locate()の所で COORD dwPos; dwPos.X = (SHORT)x; dwPos.Y = (SHORT)y; とやっているのですが、これは?

  • C++画像処理に困っています。。

    #include<iostream> #include<fstream> using namespace std; int main() { char outfile[]="256x256x100.bin";     ifstream fin(outfile, ios::in| ios::binary); ofstream fout; if(!fin){ cout << "ファイル1はオープンできません。endl"; return 1; } } const int SIZE=256; const int SLICE=100; signed short int* matrix= new signed short int[(SIZE)*(SIZE)*(SLICE)]; for(int i=0; i<SIZE*SIZE*SLICE; i++){ fin.read((char*) &matrix[i],sizeof(signed short int)); cout << matrix[i]; } delete[] matrix; fin.close(); fout.close(); return 0; } 上のように256x256x100の三次元データ(XxYxZ)を読み込む事ができ、256 pixelx256 pixelの画像が100枚表示することが出来ました。 次に、その画像データをXZ軸方面から見た画像データにしたいのですが、どのようにすればいいのでしょうか? たぶんY方向のデータを足し算して平均を求めればよいとは思うのですが、 プログラミング初心者なので、処理の方法が全く思い浮かびません。 どなたか教えて頂けますでしょうか?

  • 置換をするプログラム

    visual C++で入力された文字列に対し、#があったら%に置換するプログラムを作っています。insertを使おうと思うのですが、よくわかりません ずっと考えているのですが、ここから1週間進んでいません 教えてください #include<iostream> #include<string> #include<cstdlib> using namespace std; int main(void) { string a,s; cout <<"文字列を入力してください"<<endl; getline(cin,s); int i,j=0; while( j!= s.npos) { i=s.find_first_of("#",j); if(i==s.npos){ cout << s.substr(j) << endl; break; } if( i>0) { cout << s.substr(j, i-j); j=i; } i=s.find_first_not_of("#",j); if( i== s.npos) { a=s.substr(j); j=i; } else{ a=s.substr(j,i-j); j=i; } for(i=0; i<s.length(); i++) { if (s[i]== "#"){ s.insert(i,"%"); } cout<<a.s[i]<<endl; } } return 0; }

専門家に質問してみよう