3

私はcで開発するのが初めてです。きっとあなたの助けが必要な日が来るでしょう。そして、私は今回が今だと思います:)

私がやろうとしていること: C で MySQL Api を試しています。そのために、構造体を使用して SQLQuery とそのすべてのパラメーター (選択または挿入用のユーザー データなど) を保持したいと考えていました。

次に、いくつかの関数を使用して、文字列を追加、削除、およびコンパイルして、クエリで使用したいと考えました。

私の createSqlQuery 関数を使用するには、SQLQuery 構造への参照をそれに渡し、関数内で変更したいと思います。その関数が終了した後、スコープ外に出てはならず、メイン関数で引き続き使用できます。

それが私が現在立ち往生しているところです。私の問題はかなり単純だと思いますが、何時間も見て試してみると、解決策が見えなくなります。この質問を使用して:構造体へのポインター/参照を関数に渡す作成関数が終了した後も構造体を引き続き使用できる方法で、最終的に作業コードができました。

しかし、何らかの理由で、構造に何かを割り当てることができないため、コードをさらにコンパイルできません。

エラーメッセージ:

main.c:127:10: エラー: 構造体または共用体ではないメンバー 'addParam' の要求

これは、create 関数に 2 番目の * を追加してポインターへのポインターを取得した後に発生しました (他のスタックオーバーフローの質問を参照)。

これは私がこれまでに持っているものです:

typedef struct sqlQuery sqlQuery;

struct sqlQuery{
    char *queryS;
    char **params; //array of array of chars to hold the params to replace %? in the query
    bool (*addParam)(sqlQuery*, char*);
    bool (*compile)(sqlQuery*);
};

int main(){
/* ...  */
    sqlQuery *testQuery = NULL;
    printf("%p\n", &testQuery);
    printf("%p\n", testQuery);
    createSqlQuery(&testQuery,"SELECT * FROM test WHERE name = '%?'");
    printf("%p\n", testQuery);
    if (testQuery != NULL) printf("working, testQuery still assigned");
    //testQuery->addParam(testQuery, "test");
    //freeSqlQuery(testQuery);

    exit(EXIT_SUCCESS);
}

bool createSqlQuery(sqlQuery **query, char *queryString){
    *query = (struct sqlQuery *) malloc(sizeof(struct sqlQuery));  //get heapspace for sqlQuery Struct
    printf("%p\n", *query);
    //query->addParam = __sqlQueryAddParam;      //link param function pointer
    //query->compile = __compileSqlQuery;        //link compile function pointer
    *query->queryS = queryString;               //save pointer to query String
    //^^^ this is where the error occurs

    return true;
}

また、次の組み合わせとバリエーションも試しました。

(sqlQuery *)*query->queryS = queryString;

**、または &...

私が苦労していることを理解していただければ幸いです。単純だと思いますが、本当に理解できないようです:)

前もって感謝します!

4

4 に答える 4

5

これは、メンバー アクセス演算子の優先順位が逆参照演算子よりも高いため、演算子の優先順位が原因です。変化する:->*

*query->queryS = queryString; 

に:

(*query)->queryS = queryString;

他の:

  • からの戻り値をキャストしないでくださいmalloc()
  • このコードは、読み取り専用の文字列リテラルのアドレスを に割り当てていますchar*。文字列を使用const char*またはコピーします ( malloc()/を使用するstrcpy()strdup()、実装で提供されている場合)。
  • dだったfree()ことを思い出してください。malloc()
于 2013-06-04T13:34:38.093 に答える
0

より簡単にするために試してください

bool createSqlQuery(struct sqlQuery **ptrresultquery, char *queryString)
{
    struct sqlQuery *query = (struct sqlQuery *) malloc(sizeof(struct sqlQuery));  //get heapspace for sqlQuery Struct

     query->addParam = __sqlQueryAddParam;      //link param function pointer
     query->compile = __compileSqlQuery;        //link compile function pointer
     query->queryS = queryString;               //save pointer to query String

     // write the local pointer back via parameter ptr
     *ptrresultquery= query;

     return true;
}

それ以外の場合、構文でやりたいことは

    (*ptrresultquery)->queryS= queryString;
于 2013-06-04T13:35:32.270 に答える
0

createSqlQuery()関数が新しく作成されたクエリを返すようにする方が良いでしょう。これにより、実際のコードでの使用がはるかに簡単になります。

ただし、ブール値を返し、ポインターへのポインターを受け入れることを主張する場合は、関数内で一時ポインターを使用する方が簡単です。

bool createSqlQuery(sqlQuery **query, char *queryString){
  struct sqlQuery *q = malloc(sizeof *q);
  if( q != NULL ) {
    q->addParam = __sqlQueryAddParam;
    q->compile = __compileSqlQuery;        //link compile function pointer
    q->queryS = queryString;
    *query = q;
  }
  return q != NULL;
}

また、文字列のメモリ処理を確認し、2 つのアンダースコアで始まる記号を避けてください。

于 2013-06-04T13:35:38.490 に答える
0

(*query)->queryS = queryString;仕事をします

main の後に関数を呼び出す場合は、プロトタイプを使用します

bool createSqlQuery(sqlQuery **query, char *queryString);
于 2013-06-04T13:37:22.467 に答える