プロが教えるわが家の防犯対策術!

二次元の配列をメンバ変数の値を取得したいのですが、上手くいきません。

どなたか教えて頂けないでしょうか。

class DML_Backup
{
 char ecoFileList[256][32];
public:
char GetsearchEcoDataFileName(){return **ecoFileList;}
}

void main()
{
DML_Backup m_ecoData;
char ecoFileList[256][32];

**ecoFileList = m_ecoData.GetsearchEcoDataFileName();

}

A 回答 (7件)

> 自宅の環境の2005では通りました。

ただ会社の環境だと下記のエラーが出たと思います。

「会社の環境」とやらがわかん。知らんよそんなもん。
    • good
    • 0

これではどうでしょう。

2005で通るか自信はないのだけれども。

#include <Windows.h>
#include <map>
#include <vector>
#include <string>
#include <iostream>

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); }
int size() const { return files_.size(); }
};

int main() {
DML_Backup dml;
dml.search("d:\\work\\*.cpp");
int n = dml.size();
for ( int i = 0; i < n; ++i) {
cout << dml[i] << endl;
}
}

この回答への補足

親切にありがとうございます。自宅の環境の2005では通りました。ただ会社の環境だと下記のエラーが出たと思います。何か分かりましたら教えて下さい。

C2665: 'std::pair<_Ty1,_Ty2>::pair' : 3 オーバーロードのどれも、すべての引数の型を変換できませんでした
with
[
_Ty1=const FILETIME,
_Ty2=int
]
c:\program files\microsoft visual studio 8\vc\include\utility(35): 'std::pair<_Ty1,_Ty2>::pair(const _FILETIME &,const _Ty2 &)' の可能性があります。
with
[
_Ty1=const FILETIME,
_Ty2=int
]

補足日時:2011/06/13 20:49
    • good
    • 0

> ただこちらの環境ではエラーになります。



コンパイラが旧いようです。
僕とこではVC++10(VS2010)でコンパイルしました。

コンパイラをupgradeするか、コードを適宜書き換える必要があります。

この回答への補足

そうですか。。実は職場で2005を使っていて、これでやらないといけないのです。コードを適宜変える方法でやってみます。何か他におわかりでしたら教えて下さい

補足日時:2011/06/13 18:35
    • good
    • 0
この回答へのお礼

ありがとうございました。下記のエラーだけなんとかならないでしょうか?2005で行いました。

C2665: 'std::pair<_Ty1,_Ty2>::pair' : 3 オーバーロードのどれも、すべての引数の型を変換できませんでした
with
[
_Ty1=const FILETIME,
_Ty2=int
]
c:\program files\microsoft visual studio 8\vc\include\utility(35): 'std::pair<_Ty1,_Ty2>::pair(const _FILETIME &,const _Ty2 &)' の可能性があります。
with
[
_Ty1=const FILETIME,
_Ty2=int
]

お礼日時:2011/06/13 18:48

せっかくのC++がもったいない。


なんでわざわざcharの二次元配列使わんならんのだろ。

#include <Windows.h>
#include <map>
#include <vector>
#include <string>
#include <iostream>

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();
transform(files.begin(), files.end(), back_inserter(files_),
[](const map_type::value_type& item) { return item.second;});
}
string operator[](int inx) const { return files_.at(inx); }
int size() const { return files_.size(); }
};

int main() {
DML_Backup dml;
dml.search("d:\\work\\*.cpp");
int n = dml.size();
for ( int i = 0; i < n; ++i) {
cout << dml[i] << endl;
}
}

この回答への補足

いつも明確な回答ありがとうございます。

ただこちらの環境ではエラーになります。

こちらでも確認しますが、何か分かるようでしたら教えて下さい

kazu3.cpp
c:\documents and settings\administrator\my documents\visual studio 2005\projects\kazu\kazu3.cpp(30) : error C2958: 左側の かっこ '(' が 'c:\documents and settings\administrator\my documents\visual studio 2005\projects\kazu\kazu3.cpp(30)' にありますが正しく対応していません。
c:\documents and settings\administrator\my documents\visual studio 2005\projects\kazu\kazu3.cpp(30) : error C2059: 構文エラー : ')'
c:\documents and settings\administrator\my documents\visual studio 2005\projects\kazu\kazu3.cpp(32) : error C2143: 構文エラー : ';' が '[' の前にありません。
c:\documents and settings\administrator\my documents\visual studio 2005\projects\kazu\kazu3.cpp(19) : error C2872: 'string' : あいまいなシンボルです。
'c:\documents and settings\administrator\my documents\visual studio 2005\projects\kazu\kazu3.cpp(32) の可能性があります : DML_Backup string''
または 'c:\program files\microsoft visual studio 8\vc\include\xstring(2128) : std::string'
c:\documents and settings\administrator\my documents\visual studio 2005\projects\kazu\kazu3.cpp(19) : error C2872: 'string' : あいまいなシンボルです。
'c:\documents and settings\administrator\my documents\visual studio 2005\projects\kazu\kazu3.cpp(32) の可能性があります : DML_Backup string''
または 'c:\program files\microsoft visual studio 8\vc\include\xstring(2128) : std::string'
c:\documents and settings\administrator\my documents\visual studio 2005\projects\kazu\kazu3.cpp(19) : error C2923: 'std::multimap' : 'string' は、有効な テンプレート 型引数 (パラメータ '_Ty') ではありません。
c:\documents and settings\administrator\my documents\visual studio 2005\projects\kazu\kazu3.cpp(32) : 'string' の宣言を確認してください。
c:\documents and settings\administrator\my documents\visual studio 2005\projects\kazu\kazu3.cpp(25) : error C2665: 'std::pair<_Ty1,_Ty2>::pair' : 3 オーバーロードのどれも、すべての引数の型を変換できませんでした
with
[
_Ty1=const FILETIME,
_Ty2=int
]
c:\program files\microsoft visual studio 8\vc\include\utility(35): 'std::pair<_Ty1,_Ty2>::pair(const _FILETIME &,const _Ty2 &)' の可能性があります。
with
[
_Ty1=const FILETIME,
_Ty2=int
]
引数リスト '(FILETIME, CHAR [260])' を一致させようとしているとき
c:\documents and settings\administrator\my documents\visual studio 2005\projects\kazu\kazu3.cpp(30) : error C2059: 構文エラー : '['
c:\documents and settings\administrator\my documents\visual studio 2005\projects\kazu\kazu3.cpp(30) : error C2143: 構文エラー : ')' が '{' の前にありません。
c:\documents and settings\administrator\my documents\visual studio 2005\projects\kazu\kazu3.cpp(30) : error C2143: 構文エラー : ';' が '{' の前にありません。
c:\documents and settings\administrator\my documents\visual studio 2005\projects\kazu\kazu3.cpp(30) : error C2065: 'item' : 定義されていない識別子です。
c:\documents and settings\administrator\my documents\visual studio 2005\projects\kazu\kazu3.cpp(30) : error C2228: '.second' の左側はクラス、構造体、共用体でなければなりません
型は ''unknown-type'' です。
c:\documents and settings\administrator\my documents\visual studio 2005\projects\kazu\kazu3.cpp(30) : error C3861: 'transform': 識別子が見つかりませんでした
c:\documents and settings\administrator\my documents\visual studio 2005\projects\kazu\kazu3.cpp(32) : error C2270: '[]' : メンバでない関数が、メモリ モデル修飾子を伴って宣言されています。
c:\documents and settings\administrator\my documents\visual studio 2005\projects\kazu\kazu3.cpp(32) : error C4430: 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません
c:\documents and settings\administrator\my documents\visual studio 2005\projects\kazu\kazu3.cpp(32) : error C2801: 'operator []' は静的でないメンバでなければなりません
c:\documents and settings\administrator\my documents\visual studio 2005\projects\kazu\kazu3.cpp(32) : error C2065: 'files_' : 定義されていない識別子です。
c:\documents and settings\administrator\my documents\visual studio 2005\projects\kazu\kazu3.cpp(32) : error C2228: '.at' の左側はクラス、構造体、共用体でなければなりません
型は ''unknown-type'' です。
c:\documents and settings\administr

補足日時:2011/06/12 21:15
    • good
    • 0

質問の処理をこなすだけなら


class DML_Backup
{
 char ecoFileList[256][32];
public:
char** GetsearchEcoDataFileName(){return ecoFileList;}
}

void main()
{
DML_Backup m_ecoData;
char ecoFileList[256][32];

memcpy(ecoFileList, m_ecoData.GetsearchEcoDataFileName(), sizeof(char) * 256 * 32);
}
で可能です。

ただし、このGetsearchEcoDataFileName()の実装では ecoFileList を private にした意味がありません。
 m_ecoData.GetsearchEcoDataFileName()[0][0] = '\0';
というようなコードでクラス外から好き勝手に値を変更できるからです。

というか、このデータの持ち方を見ると前の質問
http://oshiete.goo.ne.jp/qa/6798323.html
で私が心配した「呼び出し元で想定した個数以上ファイルが存在した場合」と「ファイル名が極端に長い場合」に問題があるようです。
これでは .eco ファイルが 300 個あった場合や、 filenameistoolongtostockinchar32field.eco というようなファイル名の .eco ファイルがあったときに問題が発生します。

処理全体が見えないから全体から見て適切かどうかわかりませんが、
class DML_Backup
{
 std::vector<std::string> ecoFileList;
public:
 std::vector<std::string>::size_type GetsearchEcoDataSize() const {return ecoFileList.size();}
 std::string GetsearchEcoDataFileName(int index) const {return ecoFileList[index];}
// あるいは
// const std::string& GetsearchEcoDataFileName(int index) const {return ecoFileList[index];}
}

void main()
{
DML_Backup m_ecoData;
// char ecoFileList[256][32]; :不要

for(int i = 0; i < m_ecoData.GetsearchEcoDataSize(); i++){
 // 各ファイルに対する処理を行う
 // ファイル名は GetsearchEcoDataFileName(i) で取得可能、char* でほしいなら c_str() を使えばでできる
}
}

とするか、ファイルリストを表すクラスを導入するかすべきではないでしょうか。
    • good
    • 0

プログラムの記述方法が明らかに間違っています。



>二次元の配列をメンバ変数の値を取得したい
とありますが、C言語では、以下2種類の解釈があります。
 解釈ア.メンバ変数から、ポインタへ、二次元配列のポインタ値を取得したい
 解釈イ.メンバ変数から、別の二次元配列へ、配列の値全て(256×32)をコピーしたい

解釈アの場合、「ポインタの宣言」と「ポインタの参照」を混同していますよ。
解釈イの場合、配列の値のコピーはmemcpy関数等でコピー操作を行う必要があります。代入では配列をコピーできません。

解釈アの場合:
class DML_Backup {
  char ecoFileList[256][32];
 public:
  char GetsearchEcoDataFileName(){return ecoFileList;}
}
void main(){
 DML_Backup m_ecoData;
 char (*ecoFileList)[32];
 ecoFileList = m_ecoData.GetsearchEcoDataFileName();
}

解釈イの場合:
class DML_Backup {
  char ecoFileList[256][32];
 public:
  void GetsearchEcoDataFileName(char p[256][32]){
   memcpy(p,ecoFileList,sizeof(ecoFileList));
   return;
  }
}
void main(){
 DML_Backup m_ecoData;
 char ecoFileList[256][32];
 m_ecoData.GetsearchEcoDataFileName(ecoFileList);
}

この回答への補足

ご回答ありがとうございます。

ただ下記の場合にエラーが出るようなのですが。

class DML_Backup {
char ecoFileList[256][32];
public:
char GetsearchEcoDataFileName(){return ecoFileList;}
 //error C2440: 'return' : 'char [256][32]' から 'char' に変換できません。
};

void main(){
DML_Backup m_ecoData;
char (*ecoFileList)[32];
ecoFileList = m_ecoData.GetsearchEcoDataFileName();
// error C2440: '=' : 'char' から 'char (*)[32]' に変換できません。
}

補足日時:2011/06/12 18:34
    • good
    • 0

大きな間違いは2つ。



> char GetsearchEcoDataFileName(){return **ecoFileList;}
とあるように、 GetsearchEcoDataFileNameが返すのは 「char型が一つ」 です。
char型は、よくある処理系では8ビットの整数です。
配列は返しません。

実際に、 **echoFileList と、charを返しています。
**echoFileList → *(echoFileList[0]) → echoFIleList[0][0] です。
これはmain関数での
> **ecoFileList = m_ecoData.GetsearchEcoDataFileName();
でも同じです。echoFIleList[0][0] に受け取ってます。

もう一つは、
ecoFileList = m_ecoData.GetsearchEcoDataFileName();
として = で配列の中身をコピーしたいのであれば、普通はできません。配列を=でつないでも、配列の内容をコピーするようには作られてないからです。
    • good
    • 0

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