1

の特定のフィールド値を確認しようとしていifます。これらの値のほとんどはNULLMySQL にあります。

全てを台無しにしているそうです。

そうです

while ((row = mysql_fetch_row(res)) !=NULL){
    if(row[1] != "-1"){
        rows.push_back(row[0]);
    }
}

のフィールドrow[1]は、、、またはINT LENGTH 1に等しいです。ほとんどはですが、一部はです。すべての値を次のように出力すると思います(少なくとも、これまでに機能させることができた唯一の方法です)。1-1NULLNULL-1mysql.hchar*

とにかく、妙にrows満たされますが、「無」で満たされています。それが空の文字列なのか、それとも何なのかさえわかりません。

助けてください。

よろしくお願いします!


ループの前後にダッシュを入れstd::coutましrows[i]た。大量のsforを出力します。--

std::coutraw の場合、正常にrow[0]出力されます。


私たちのために2012:

std::vector< char* > rows;

while ((row = mysql_fetch_row(res)) !=NULL){
    std::cout << "-" << row[0] << "-" << std::endl;
    if(row[1] != "-1"){
        rows.push_back(row[0]);
    }
}

std::cout << "Valids:" << std::endl;
for(int i = 0; i < rows.size(); ++i)
{
    std::cout << "id: -" << rows[i] << "-" << std::endl;
}

これを使うと

if(row[1] && row[1] != "-1")

if逆に動作します。

注: の をインクリメントし、intwhileとをcout編集しました。カウンタは、、およびを与えます。rowsinvalidRows389rows.size() 2invalidRows.size() 387

やってからできるか見てみようcout row[0] if


cout正しいデータを出力したrow[0]後。if


if(row[1] != "-1")与える...forbids comparison between pointer and integer...


理由mysql.h:

CentOS。私はそれについてほとんど何も見つけられず、ホストがサポートするものは何もありません。


if(row[1] && std::string(row[1]).compare("-1") != 0)すべてを入れるinvalidRows

なしrow[] && gavewhat(): basic_string::_S_construct NULL 無効 中止`


答え

それはif(row[1] && std::string(row[1]).compare("-1") == 0)ずっとでした!私のロジックは、すべての C++ クラッシュ コースでめちゃくちゃになりました。

そして使用std::vector< std::string >するrow[x]と、pushedにすることができます_back

4

1 に答える 1

2

まず最初に: 使用している API は C API です。それについて本質的に悪いことは何もありませんが、C++ にはこれに使用できるより優れたツールがあるため、不要と思われる多くのものに対処する必要があることを意味します。したがって、可能であれば、MySQL++ のような C++ ラッパーを使用する必要があります: http://tangentsoft.net/mysql++/ (この提案のすべてのクレジットは、以下のコメントで @Non-Stop Time Travel に送られます)


元のコードでは、文字列を比較しているのではなく、アドレスを比較しています。条件は、格納されrow[1]ているメモリ アドレスを定数文字列リテラルのメモリアドレスと比較します"-1"。あなたが実際に望むのは(あなたが固執する場合char *)ですstrcmpC++ Compare char array with string

row[0]また、一時的なポインターをプッシュバックしています。これは、while ループの反復ごとに再割り当てされます! これらのコピーを作成し、コピーへのポインターを保存する必要があります。

これは、これにどのようにアプローチできるかについての非常に簡単なアイデアです。ただし、あまり良いC++ではありません(実際、ベクトルとcoutがなければ、Cである可能性があります。理由については上記を参照してください。):

#include <string.h>

std::vector<char*> rows;
while ((row = mysql_fetch_row(res)) !=NULL){
    if(strcmp(row[1],"-1") != 0){
        char * store = new char[strlen(row[0])+1];
        strncpy(store ,row[0] ,strlen(row[0])+1);
        rows.push_back(store);
    }
}
std::cout << "Valids:" << std::endl;
for(int i = 0; i < rows.size(); ++i)
{
    std::cout << "id: -" << rows[i] << "-" << std::endl;
}

//clean up
for(int i = 0; i < rows.size(); ++i)
{
    delete [] rows[i];
}

一般に、C++ で文字列を処理する場合は、代わりにstd::stringandを使用することをお勧めしますが、これには問題があります。mysql の行がバイナリ データを保持している場合、null で終わる文字列は保証されません (ここで MYSQL_ROW の仕様を参照してください: http://dev.mysql.com/doc/refman/5.0/en/c-api-data-structures.html )。以下のコメントでNon-Stop Time Travelが指摘しているように、内部s をサポートしていますが、以下のコード例はそれらでは機能しません。std::string::comparestd::string\0

#include <string>

//this particular code works only if row[0] and row[1] are nullterminated

std::vector<std::string> rows;
while ((row = mysql_fetch_row(res)) !=NULL){
    if(std::string(row[1]).compare("-1") != 0){
        rows.push_back(std::string(row[0]));
    }
}
std::cout << "Valids:" << std::endl;
for(int i = 0; i < rows.size(); ++i)
{
    std::cout << "id: -" << rows[i] << "-" << std::endl;
}

//cleaning up the vector of strings is not necessary! yay!

)

于 2013-01-24T02:01:42.510 に答える