1

次のやや単純なコードを使用して、Postgresテーブルにいくつかの整数を挿入しようとしています。

#include <libpq-fe.h>
#include <stdio.h>
#include <stdint.h>

int main() {
  int64_t i = 0;
  PGconn * connection = PQconnectdb( "dbname='babyfood'" );
  if( !connection || PQstatus( connection ) != CONNECTION_OK )
    return 1;
  printf( "Number: " );
  scanf( "%d", &i );

  char * params[1];
  int param_lengths[1];
  int param_formats[1];
  param_lengths[0] = sizeof( i );
  param_formats[0] = 1;
  params[0] = (char*)&i;
  PGresult * res =  PQexecParams( connection, 
                                  "INSERT INTO intlist VALUES ( $1::int8 )",
                                  1,
                                  NULL,
                                  params,
                                  param_lengths,
                                  param_formats,
                                  0 );
  printf( "%s\n", PQresultErrorMessage( res ) );
  PQclear( res );
  PQfinish( connection );
  return 0;
}

次の結果が得られます。

数値: 55
エラー:整数が範囲外です
数値: 1
エラー:整数が範囲外です

int64_tは、どのプラットフォームでも常に8バイト整数に収まると確信しています。私は何が間違っているのですか?

4

3 に答える 3

3

それ以外の:

params[0] = (char*)&i;

あなたが使用する必要があります:

#include <endian.h>
/* ... */
int64_t const i_big_endian = htobe64(i);
params[0] = (char*)&i_big_endian;

関数は、htobe64リトル エンディアンではエンディアンを切り替え、ビッグ エンディアンでは何もしません。

プログラムが PowerPC、Alpha、Motorola、SPARC、IA64 などのビッグエンディアン/バイエンディアンのコンピューターと互換性がなくなるため、関数を捨ててくださいflip_endian。プログラムがそれらで実行されることを期待していなくても、それは悪いスタイルです。 、遅く、エラーが発生しやすい。

于 2009-08-20T07:55:56.743 に答える
1

リトルエンディアン (つまり x86) の 64 ビット符号付き整数はビッグエンディアンの 64 ビット整数に収まる必要があり、その逆も同様であるため、これはエンディアンの問題のようですが、まだ完全には説明されていません。破損する。ただし、整数のエンディアンを交換すると、正しい値が得られます。スワップは、次の関数で行われます。

int64_t flip_endian( int64_t endi ) {
  char* bytearray;
  char swap;
  int64_t orig = endi;
  int i;

  bytearray = (char*)&orig;

  for( i = 0; i < sizeof( orig )/2; ++i ) {
    swap = bytearray[i];
    bytearray[i] = bytearray[ sizeof( orig ) - i - 1 ];
    bytearray[ sizeof( orig ) - i - 1 ] = swap;
  }

  return orig;

}
于 2009-08-19T21:00:34.220 に答える
-1

libpqにフォーマットが何であるかを伝えていないため、32ビットintとして渡されてから64ビットにキャストされると思います。

パラメーターの int8 (20) の oid を使用して、paramTypes の配列を指定してみてください。

于 2009-08-19T20:57:24.930 に答える