0

私はこの次のコードを持っています:

template <class T>
bool loadCSV (const QString &filename, map<T,int> &mapping){
    QFile boxfile;
    boxfile.setFileName(filename);
    QString line;
    QStringList list;

    if (!boxfile.open(QIODevice::ReadOnly)){
        cout << "Could not open box data file." << endl;
        return false;
    }

    QTextStream stream2( &boxfile ); 

    while (!stream2.atEnd()){
        line = stream2.readLine();
        list = line.split(',');
        mapping[list.front().toInt()]=list.back().toInt();      
    }

    return true;
}

CSVファイルを取得し、次の場所に貼り付けます。

map<int, int> mapping

構造。これはテンプレートとして実行されるため、データをに貼り付けるためにも使用できます。

map<string, int> mapping

構造。これを行うには、whileループの最後の行を変更する必要がありますが、これを実現するための最良の方法がわかりません。

私はいくつかの方法を考えることができました:

  1. いくつかの方法でタイプを検出し、そこにある種の条件付き行があります(これが可能かどうか、可能であればどのように行うかは実際にはわかりません。

  2. これを行うには、QStringListにクラス関数を追加します。

私はオプション2を試し、これを行いました:

void QStringList::cInsert(map<int,int> &mapping){
    mapping[this->front().toInt()]=this->back().toInt();
}

void QStringList::cInsert(map<string,int> &mapping){
    mapping[(this->front()).toAscii()]=this->back().toInt();
}

QStringListクラスでこれらの関数を定義する必要もあったため、これは機能しませんでした。そのため、これは少し面倒になります。その代わり。QStringListから継承しようとしています:

class myQStringList: public QStringList{
    public:
        void cInsert(map<int,int> &mapping);
        void cInsert(map<string,int> &mapping);
};

void myQStringList::cInsert(map<int,int> &mapping){
    mapping[this->front().toInt()]=this->back().toInt();
}

void myQStringList::cInsert(map<string,int> &mapping){
    mapping[(this->front()).toAscii()]=this->back().toInt();
}

そして、コードを変更します。

template <class T>
bool loadCSV (const QString &filename, map<T,int> &mapping){
    QFile boxfile;
    boxfile.setFileName(filename);
    QString line;
    myQStringList list;   

if (!boxfile.open(QIODevice::ReadOnly)){
    cout << "Could not open box data file." << endl;
    return false;
}

QTextStream stream2( &boxfile ); 

while (!stream2.atEnd()){
    line = stream2.readLine();
    list = line.split(',');
        list.cInsert(mapping);
}

return true;}

しかし。line.split/listの割り当てに関連してエラーが発生します。

main.cpp:123: error: no match for 'operator=' in 'list = QString::split(const QChar&, QString::SplitBehavior, Qt::CaseSensitivity) const(((const QChar&)(&QChar(44))),  KeepEmptyParts,  CaseSensitive)'

このエラーが何であるか、また、割り当て/コピー演算子が継承されていないことに関係しているかどうかはわかりませんか?

そして、実際の新しいクラスに関連して、次のエラーが発生します。

main.cpp:104: error: no match for 'operator[]' in 'mapping[QString::toAscii() const()]'
c:/qt/mingw/bin/../lib/gcc/mingw32/3.4.2/../../../../include/c++/3.4.2/bits/stl_map.h:332: note: candidates are: _Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = std::string, _Tp = int, _Compare = std::less<std::string>, _Alloc = std::allocator<std::pair<const std::string, int> >]
main.cpp: In function `bool loadCSV(const QString&, std::map<T, int, std::less<_Key>, std::allocator<std::pair<const T,int> > >&) [with T = int]':

私はそれを単に理解していません。誰か説明してもらえますか?

また、私がこれについて行っている方法が正しいかどうかはわかりません。これに関してもアドバイスをいただければ幸いです。ありがとう。

4

3 に答える 3

2

QString から T 型への変換を関数の外に移動します。したがって、次のようなものがあります。

template< typename T>
struct converter { };

template<>
struct converter< int>
{
static int convert( const QString& source)
{
    return source.toInt();
}
};

template<>
struct converter< std::string>
{
static std::string convert( const QString& source)
{
    return source.toStdString();
}
};

template< typename T>
T convertFromString( const QString& source)
{
    return converter<T>::convert( source);
}

次に、この変換関数をループ (while 内) で使用します。

それ以外の

mapping[list.front().toInt()]=list.back().toInt();   

書きます:

mapping[ convert<T>(list.front())]=list.back().toInt();

注: クラス コンバーター (およびその 2 つの特殊化) は、convert 関数をテンプレート関数として使用できるように定義されています (必要に応じて、static_cast または boost::lexical_cast に似ています)。

コードをコンパイルしようとしませんでした。それはただの考えです。

于 2009-06-09T14:55:27.173 に答える
1

CSV ファイルに関しては、Qt は QString::section 関数を介して優れた機能を提供します。したがって、必要な列を見つけるために、ヘッダーを次のように処理します。

int AmountInd = (line.left(line.indexOf("Amount")).count(',');

その列のインデックスを取得します。次に、次の行について、その列の部分文字列を抽出します。

QString AmountStr = (line.section(',', AmountInd, AmountInd);
double Amount = AmountStr.toDouble();

セクション関数が役立つことを願っています;-)

于 2009-06-18T09:00:10.843 に答える
0

明示的にキャストすることで問題を解決しました:

list = (const myQStringList&) line.split(',');
void myQStringList::cInsert(map<string,int> &mapping){
    mapping[(string)(this->front()).toAscii()]=this->back().toInt();
}
于 2009-06-09T14:45:14.823 に答える