I'm looking for help with printing the results of an SQL statement out in C. I'm trying not to set each variable to a pointer and then using that pointer to print the variable out. If I did, I'd have like a couple hundred variables. This is what I've tried so far. I'm literally lost on how to get this to output correctly. Any help would be appreciated.
int hstmt = DBActivateSQL(hdbc, "SELECT * FROM REG_RESULTSTABLE");
if (hstmt <= 0)
{
ShowError();
}
sprintf(uutNum, "%s \n", hstmt);
while((resCode = DBFetchNext(hstmt)) == DB_SUCCESS) {
SetCtrlVal(panelHandle, PANEL_lstregulator, uutNum);
}
Prototype of DBActivateSQL is
int DBActivateSQL (int connectionHandle, char SQLStatement[]);
It is returns int.
Hence hstmt should be declared as int type.
int hstmt = DBActivateSQL(hdbc, "SELECT * FROM REG_RESULTSTABLE");
To print it to string you need use %d not %s as hsmt is of type int.
sprintf(uutNum, "%d",hstmt);
^^------------------------//Using %d instead of %s here
The functions that you want are DBFetchNext and DBGetCol* (DBGetColChar, DBGetColDouble, ...). According to the documentation page on DBGetColChar, the flow should be something like this, where you only need one variable per column:
void print_MyTable(int hdbc)
{
char *var1;
int var2;
float var3;
int statement = DBActivateSQL(hdbc, "SELECT col1, col2, col3 FROM MyTable");
int resultCode;
while ((resultCode = DBFetchNext(statement)) == DB_SUCCESS) {
if ((resultCode = DBGetColChar(statement, 1, &var1, "")) != DB_SUCCESS) {
// Handle the error
break;
}
if ((resultCode = DBGetColInt(statement, 2, &var2)) != DB_SUCCESS) {
// Handle the error
DBFree(var1);
break;
}
if ((resultCode = DBGetColFloat(statement, 3, &var3)) != DB_SUCCESS) {
// Handle the error
DBFree(var1);
break;
}
// Print the values
printf("col1: %s, col2: %d, col3: %f\n", var1, var2, var3);
// Free the string's memory
DBFree(var1);
}
statement = DBDeactivateSQL(statement);
}
Related
I'm trying to insert a float value into my table "measurements" in column "thera0"
Can someone help me?
I'm beginner, don't be too hard :D
This is my first try error code
passing argument 5 of ‘PQexecParams’ from incompatible pointer type [-Wincompatible-pointer-types]
PGresult *res_values = PQexecParams(conn, "INSERT INTO measurements(theta0) VALUES($1)",1,NULL,buffer_theta0,NULL,NULL,0);
char*
expected ‘const char * const*’ but argument is of type ‘char *’
const char *const *paramValues,
~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~
And this is my second try error code
memory access error
float theta = 0.2;
char buffer_theta0[10];
sprintf(buffer_theta0,"%f",theta);
PGresult *res_values = PQexecParams(conn, "INSERT INTO measurements(theta0) VALUES($1)",1,NULL,buffer_theta0,NULL,NULL,0);
float theta = 0.2;
char buffer_theta0[10];
sprintf(buffer_theta0,"%f",theta);
const char * const paran[]= {buffer_theta0};
PGresult *res_values = PQexecParams(conn, "INSERT INTO measurements(theta0) VALUES($1)",1,NULL,paran,NULL,NULL,0);
Maybe this can help, more information is needed to reproduce the problem.
See comments inline for explanations.
Good luck!
See this discussion of how to use C to program prepared statements
The PQexecParams function creates a prepared statement and executes it. The second parameter is the SQL statement. The third parameter is the number of parameters passed. Passing NULL to the fourth parameter means that the server should figure out the parameter types. The fifth parameter is a pointer to an array of strings containing parameters. The next two parameters are only relevant with binary parameters. Passing 0 to the final parameter we obtain result in text format, 1 in binary format.
gcc -I /usr/local/opt/libpq/include main.c -L /usr/local/opt/libpq/lib -lpq
./a.out
1 'Audi' 52642 0.52642
2 'Mercedes' 57127 0.57127
3 'Skoda' 9000 0.9
4 'Volvo' 29000 0.29
5 'Bentley' 350000 0.35
6 'Citroen' 21000 0.21
7 'Hummer' 41400 0.414
8 'Volkswagen' 21600 0.216
#include <stdio.h>
#include <stdlib.h>
#include <libpq-fe.h>
void do_exit(PGconn *conn, PGresult *res) {
fprintf(stderr, "%s\n", PQerrorMessage(conn));
PQclear(res);
PQfinish(conn);
exit(1);
}
int main() {
// Data structure to hold the data going into the database
// using a variety of incoming data types, text, integer, and float
struct rawdata {
char* name;
int value;
float megaValue;
};
// These are the values to be inserted into the measurements table
struct rawdata rawtable [] =
{
{ "Audi" , 52642 , 0.52642 },
{ "Mercedes" , 57127 , 0.57127 },
{ "Skoda" , 9000 , 0.9 },
{ "Volvo" , 29000 , 0.29 },
{ "Bentley" , 350000 , 0.35 },
{ "Citroen" , 21000 , 0.21 },
{ "Hummer" , 41400 , 0.414 },
{ "Volkswagen" , 21600 , 0.216 }
};
// Here is the database connection being used
PGconn *conn = PQconnectdb("user=atl dbname=nameofdatabase");
if (PQstatus(conn) == CONNECTION_BAD) {
fprintf(stderr, "Connection to database failed: %s\n", PQerrorMessage(conn));
PQfinish(conn);
exit(1);
}
// To be more helpful to others, create the table in each example
// this allows everyone to see the table format and how it was created
// sometimes the error is in the way tables are created
PGresult *res = PQexec(conn, "DROP TABLE IF EXISTS measurements");
if (PQresultStatus(res) != PGRES_COMMAND_OK) { do_exit(conn, res); }
PQclear(res);
res = PQexec(conn, "CREATE TABLE measurements ( measure_id serial PRIMARY KEY, col1 text, col2 integer, col3 float );" );
if (PQresultStatus(res) != PGRES_COMMAND_OK) { do_exit(conn, res); }
PQclear(res);
// This is related to the ask about how to insert values into a table using PQexecParams
// This is the string that specifies the command and the params
char *sinto = "INSERT INTO measurements VALUES($1,$2,$3,$4)";
// This is the loop to change the params on each row (and provide a unique ID)
for(int i=0; i<sizeof(rawtable) / sizeof(rawtable[0]); i++)
{
// creating storage for params, not the best way (works though)
char p1[100], p2[100], p3[100], p4[100];
// prepare param input array by initializing array to params
const char *paramValues[] = { p1, p2, p3, p4 };
// initialize params for this iteration
sprintf( p1, "%d", i+1 ); // key
sprintf( p2, "'%s'", rawtable[i].name ); // text
sprintf( p3, "%d", rawtable[i].value ); // integer
sprintf( p4, "%0.6f", rawtable[i].megaValue ); // float
// make call to database server
res = PQexecParams(conn, sinto, 4, NULL, paramValues, NULL, NULL, 0);
if (PQresultStatus(res) != PGRES_COMMAND_OK)
do_exit(conn, res);
PQclear(res);
}
// display results
res = PQexec(conn, "SELECT * FROM measurements");
if (PQresultStatus(res) != PGRES_TUPLES_OK) {
printf("No data retrieved\n");
PQclear(res);
do_exit(conn, res);
}
int rows = PQntuples(res);
for(int i=0; i<rows; i++) {
printf("%s %s %s %s\n", PQgetvalue(res, i, 0), PQgetvalue(res, i, 1), PQgetvalue(res, i, 2), PQgetvalue(res, i, 3));
}
PQclear(res);
PQfinish(conn);
return 0;
}
I have the sturct token_t down below. It has two things in it.
type (enum)
value (union)
The reason why value is union, cz a token can be either a number or string.
The main problem is that I cannot design a proper function that can print this token out for me. Check out my void print_token(token_t* token) function. I know it's terrible. Just becase the printf() prints only either %d (decimal) or %s (string) I cannot print my token out. I want my function to print the token no matter what the value is.
// ===========================================================================
typedef enum token_type_t
{
ID, // Identifier
STR, // String
WHS, // Whitespace
LPR, // Left Parenthesis
RPR, // Right Parenthesis
LCB, // Left Curly Bracket
RCB, // Right Curly Bracket
LSB, // Left Square Bracket
RSB, // Left Square Bracket
EOF, // End Of File
EQL, // Equal Sign
SEM, // Semicolon
} token_type_t;
typedef union token_value_t
{
char* str_value;
int int_value;
} token_value_t;
typedef struct token_t
{
token_type_t type;
token_value_t value;
} token_t;
// ===========================================================================
// Here's the problem. I want this function to print the token no matter what type
// the value is, I want it to be dynamic. Is there any way to do that?
void print_token(token_t* token)
{
printf("Token { type: %d, value: %s }\n", token->type, token->value);
}
How do I print either string or integer in C?
Use a different printf() depending on type.
void print_token(const token_t* token) {
printf("Token { type: %d, value: ", token->type);
switch (token->type) {
case ID: printf("%d", token->value.int_value); break;
case STR: printf("\"%s\"", token->value.str_value); break;
// TBD code for other cases
}
printf(" }\n");
}
One solution is to print only a string, but convert the integer to a string conditionally:
For example:
void print_token( const token_t* token )
{
char buf[21] ;
printf( "Token { type: %d, value: %s }\n",
token->type,
token->type == ID ? itoa( token->value.int_value, buf, 10 ) :
token->value.str_value );
}
Noting that itoa() is not a standard function - you might consider that prohibitive if you have to implement your own just for this.
You have not specified which token types are integers and which are strings so if perhaps ID is not the only integer, the condition may be more complex such as:
void print_token( const token_t* token )
{
char buf[21] ;
printf( "Token { type: %d, value: %s }\n",
token->type,
token->type == ID ||
token->type == EOF ? itoa( token->value.int_value, buf, 10 ) :
token->value.str_value );
}
If you have more more integer types than string types you would do better to swap the test.
If the are just one or two of one token type and the rest are of the other, and you have a suitable integer-to-string function, the above solution is succinct, but might get cumbersome if that are more than a few of both types. In that case consider the solution below.
A switch/case using of case "fall-through" cases and a default may be easier to maintain an does not need an integer-to-string fucntion:
void print_token( const token_t* token )
{
printf( "Token { type: %d, value: ", token->type ) ;
switch (token->type)
{
// Stack all the integer token cases here
case ID :
case EOF :
printf("%d", token->value.int_value) ;
break ;
// Everything is a string
default:
printf( "\"%s\"", token->value.str_value ) ;
break;
}
printf(" }\n");
}
Again you might swap the explicit cases and default if there are more string tokens than integer.
I'm using the LXLE 14.04 distribution of Linux.
I want to write a C program to read commands, interpret and perform them. I'd like the program to be efficient, and I do not want to use
a linked list.
The commands are operations on sets.
Each set can contain any of the values from 0 through 127 inclusive.
I decided to represent a set as an array of characters, containing 128 bits.
If bit at position pos is turned on then the number pos is in the set and if the bit at position pos is turned off then the number pos is
not present in the set. For example, if the bit at position 4 is 1, then the number 4 is present in the set, if the bit at position 11 is 1 then the number
11 is present in the set.
The program should read commands and interpret them in a certain way.
There are a few commands: read_set, print_set, union_set, intersect_set, sub_set and halt.
For example, the command read_set A,1,2,14,-1 in the terminal will cause the reading of values of the list into the specified set in the command.
In this case the specified set in the command is A. The end of the list is represented by -1. So after writing this command, the set A will contain the elements 1,2,14.
This is what I have so far.
Below is the file set.h
#include <stdio.h>
typedef struct
{
char array[16]; /*Takes 128 bits of storage*/
}set;
extern set A , B , C , D , E , F;
This is the file main.c
#include <stdio.h>
#include "set.h"
#include <string.h>
#include <stdlib.h>
set A , B , C , D , E , F; /*Variable definition*/
void read_set(set s,char command[])
{
int i, number = 0 , pos;
char* str_num = strtok(NULL,"A, ");
unsigned int flag = 1;
printf("I am in the function read_set right now\n");
while(str_num != NULL) /*without str_num != NULL get segmentation fault*/
{
number = atoi(str_num);
if(number == -1)
return;
printf("number%d ",number);
printf("str_num %c\n",*str_num);
i = number/8; /*Array index*/
pos = number%8; /*bit position*/
flag = flag << pos;
s.array[i] = s.array[i] | flag;
str_num = strtok(NULL, ", ");
if(s.array[i] & flag)
printf("Bit at position %d is turned on\n",pos);
else
printf("Bit at position %d is turned off\n",pos);
flag = 1;
}
}
void print_set(set s)
{
unsigned int flag = 1; int in_set = 0;
int i = 0;
while(s.array[i] != -1)
{
if(s.array[i] & flag)
{
in_set = s.array[i];
printf("%d,",in_set );
}
i++;
flag = 1;
}
}
int main()
{
#define CMD_LENGTH 256
char command[CMD_LENGTH]; char* letter;
printf("Please enter a command");
gets(command);
letter = strtok(command,"read_set ,");
switch(*letter)
{
case 'A':
{
read_set(A,command);
break;
}
case 'B':
{
read_set(B,command);
break;
}
case 'C':
{
read_set(C,command);
break;
}
case 'D':
{
read_set(D,command);
break;
}
case 'E':
{
read_set(E,command);
break;
}
case 'F':
{
read_set(F,command);
break;
}
}
return 0;
}
Clearly, it is not a good practice to write a bunch of switch statements and using strtok for each command, and repeating the code written in the main function for each command in order to call the different functions. I thought about using a pointer to a generic function, but since each function receives different parameters,
I do not think this is going to work.
Is there a better way of doing this?
Thanks in advance!
Update #1:
Here's the code. I've made some changes to it.
#include <stdio.h>
#include "set.h"
#include <string.h>
#include <stdlib.h>
set A , B , C , D , E , F; /*Variable definition*/
set sets[6];
/*Below I want to initialize sets so that set[0] = A set[1] = B etc*/
sets[0].array = A.array;
sets[1].array = B.array;
sets[2].array = C.array;
sets[3].array = D.array;
sets[4].array = E.array;
sets[5].array = F.array;
void read_set(set s,char all_command[])
{
int i, number = 0 , pos;
char* str_num = strtok(NULL,"A, ");
unsigned int flag = 1;
printf("I am in the function read_set right now\n");
while(str_num != NULL) /*without str_num != NULL get segmentation fault*/
{
number = atoi(str_num);
if(number == -1)
return;
printf("number%d ",number);
printf("str_num %c\n",*str_num);
i = number/8; /*Array index*/
pos = number%8; /*bit position*/
flag = flag << pos;
s.array[i] = s.array[i] | flag;
str_num = strtok(NULL, ", ");
if(s.array[i] & flag)
printf("Bit at position %d is turned on\n",pos);
else
printf("Bit at position %d is turned off\n",pos);
flag = 1;
}
}
typedef struct
{
char *command;
void (*func)(set,char*);
} entry;
entry chart[] = { {"read_set",&read_set} };
void (*getFunc(char *comm) ) (set,char*)
{
int i;
for(i=0; i<2; i++)
{
if( strcmp(chart[i].command,comm) == 0)
return chart[i].func;
}
return NULL;
}
int main()
{
#define PER_CMD 256
char all_comm[PER_CMD]; void (*ptr_one)(set,char*) = NULL; char* comm; char* letter;
while( (strcmp(all_comm,"halt") != 0 ) & (all_comm != NULL))
{
printf("Please enter a command");
gets(all_comm);
comm = strtok(all_comm,", ");
ptr_one = getFunc(comm);
letter = strtok(NULL,",");
ptr_one(A,all_comm);
all_comm[0] = '\0';
letter[0] = '\0';
}
return 0;
}
I get the following compile error:
main.c:9:8: error: expected ���=���, ���,���, ���;���, ���asm��� or ���attribute��� before ���.��� token
What's my mistake? How can I fix this?
Thanks a lot! #Claim Yang
However,in your case, using switch is almost the best solution to this.
Another way without switch is using a simple way to get an index. Here is a simple solution.
set sets[6];
read_set(sets[*letter - 'A'], command);
Then if you need to read a command, another array of pointers to functions is needed. Like below:
void (*functions[3])(set,char[]);
functions[0] = read_set;
And so on.
The point is coverting your string to an int, so it can be seen as an index of an array.
Then call functions like functions[string_to_int(string)](set,char[]);
I have a code like this
int i;
for(i=0; i<n ; i++)
{
....
char* ref_error = "";
if( isSeatAvailable(&tmp, movie_name, seat_number, &ref_error) == 0)
{
printf("available %s\n", seat_number);
}
else
{
logError(ref_error);
}
....
}
If isSeatAvailable returns 0, it works perfectly, but it returns -1 and the program continues to else statement, the variables breaks down: like n becomes 4509408 etc.
The thing is,
If I re-write code like this and call isSeatAvailable method outside of if statement, it works perfect!
int i;
for(i=0; i<n ; i++)
{
....
int res = isSeatAvailable(&tmp, movie_name, seat_number, &ref_error);
if( res == 0)
{
printf("available %s\n", seat_number);
}
else
{
logError(ref_error);
}
....
}
What might cause the problem here?
Here's the method I'm calling
int isSeatAvailable(hall** halls,char* movie_name,char* seat_no, int ticket_count, char** ref_error)
{
....
sprintf(*ref_error,"Seat %s is not defined at %s.",seat_no,tmp->hall_name);
....
}
The problem is in the call to sprintf. The first parameter ref_error comes from:
char* ref_error = "";
And now sprintf tries to overwrite the constant "" with the error message. Strange things will follow!
sprintf needs a real buffer (of sufficient size) to store the message into. Not just a pointer.
I have the next SQLITE3 commands that generates a file with more than 60 million records:
.mode csv
.output matppp.csv
select mat, ppp from matppp order by mat;
.output stdout
How can I include these commands into a C program using:
sqlite3_exec(db, "..........", NULL, 0, &db_err);
?
When I attempt to do it myself, the c program generates an expression error when executing.
Thanks!!
If you want to do this within C (as opposed to piping something to sqlite3's command line program that has those nifty dot commands) then you will have to use a callback.
For your cutting and pasting convenience, here is the code, hacked out of the Apophenia library for statistical computing.
Part I:
sqlite3 *db=NULL; //The global database handle.
static int apop_db_open(char *filename){
if (!filename)
sqlite3_open(":memory:",&db);
else
sqlite3_open(filename,&db);
if (!db)
printf("Not sure why, but the database didn't open.\n");
return 0;
}
//From the SQLite manual:
#define ERRCHECK {if (err!=NULL) {printf("%s\n",err); sqlite3_free(err); return 0;}}
apop_data * apop_sqlite_query_to_screen(char *query){
char *err = NULL;
if (db==NULL)
apop_db_open(NULL);
sqlite3_exec(db, query, The_Callback, a_param, &err);
ERRCHECK
}
Part II:
The callback will have the following form, and runs once for each line returned. Notice how the parameter a_param transfers; if you don't need it (as in this example), just set it to NULL above.
int The_Callback(void *a_param, int argc, char **argv, char **column){
for (int i=0; i< argc; i++)
printf("%s,\t", argv[i]);
printf("\n");
return 0;
}
The companion web site of the book Using SQLite has some examples. In particular, chapter 7 has some examples of the C/C++ API.
Example code: http://examples.oreilly.com/9780596521196/
I think you really want to use a callback function and perhaps fprintf() to write your formatted output to a file. Fortunately, the prototype for the callback pointer contains an extra (optional) void * which could serve as a FILE * stream, making the callback more re-usable in the future.
AFAIK, sqlite3_exec() does not offer the same interface as the sqlite3 CLI. Its just for queries, not output modifiers.
Check out the example code at the bottom of the link I gave, its very easy to use a callback function.
I am doing some experiments with SQLite with a simple test harness using a single table that contains a char string key and a single integer value. The following are pieces of source from the experimental test harness that I am using. I pulled these pieces in order to show the creation of the table along with the function I use to create a record set from a select SQL statement using the call back functionality of SQLite. There are printf() statements and fprintf() statements in various places so that I can see the results of actions as this is a simple console type application for the test harness.
Notice that there are times when you do not need the call back argument so SQLite allows you to specify a NULL pointer indicating not to bother with the call back.
And as you read over the source just remember this is an experimental hack!
The function to create the table looks like:
int CreateSetupTable (sqlite3 *db)
{
char *zErrMsg = 0;
int rc;
char *aszSqlCreate = "create table tbl1(one varchar(10), two smallint)";
char *aszSqlCreateIndex01 = "create unique index index1 on tbl1 (one)";
do {
rc = sqlite3_exec(db, aszSqlCreate, 0, 0, &zErrMsg);
if( rc!=SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
break;
}
rc = sqlite3_exec(db, aszSqlCreateIndex01, 0, 0, &zErrMsg);
if( rc!=SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
break;
}
} while (0); // loop only once to allow breaks on errors
return rc;
}
I insert some records into this table and then have a function that I call to get one or more records from the table using a select SQL statement. The select function retrieves the records and uses a call back to convert each record returned into a C struct. The C struct look like:
typedef struct {
char cKey[20];
int iValue;
} Tbl1Record;
The call back used for the record set uses a struct that contains record select management data. By this what I mean is that the call back takes as its first argument a pointer to a struct that in turn points to the location to put the transformed data along with some information about the size of the memory area. Since a select might return more than one record depending on the where clause, the call back function uses the call back struct to know how many transformed records it can put into the memory area as well as an index so that as it is putting records, it can index through the memory area in order to return multiple transformed records.
The call back management struct looks like this:
typedef struct _RecordProcessor {
void *pRecordSet;
int nRecordSetMax;
int nRecordSetActual;
} RecordProcessor;
The select function looks like:
int SelectRecord (sqlite3 *db, char *cSelect, char *cKey)
{
char *zErrMsg = 0;
int rc;
char aszSqlSelect[128];
Tbl1Record myRec[20];
RecordProcessor myProcessor;
myProcessor.pRecordSet = myRec;
myProcessor.nRecordSetActual = 0;
myProcessor.nRecordSetMax = 20;
if (cKey) {
sprintf (aszSqlSelect, "select %s from tbl1 where one='%s'", cSelect, cKey);
} else {
sprintf (aszSqlSelect, "select %s from tbl1", cSelect);
}
rc = sqlite3_exec(db, aszSqlSelect, MyRecordProcessor, &myProcessor, &zErrMsg);
if( rc!=SQLITE_OK ){
fprintf(stderr, "SQL error SelectRecord: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
} else {
int i;
for (i = 0; i < myProcessor.nRecordSetActual; i++) {
printf ("Rec #%d cKey = %s iValue = %d\n", i+1, myRec[i].cKey, myRec[i].iValue);
}
}
return rc;
}
The call back that processes each record returned by the select looks like this:
static int MyRecordProcessor (void *callBackArg, int argc, char **argv, char **azColName)
{
int iRetStatus = 0;
char *colNameTable[] = {
"one",
"two"
};
Tbl1Record *pTbl1Record = (Tbl1Record *)((RecordProcessor *)callBackArg)->pRecordSet;
if (((RecordProcessor *)callBackArg)->nRecordSetActual < ((RecordProcessor *)callBackArg)->nRecordSetMax) {
int i, j;
int iIndex = ((RecordProcessor *)callBackArg)->nRecordSetActual;
memset (pTbl1Record + iIndex, 0, sizeof(Tbl1Record));
((RecordProcessor *)callBackArg)->nRecordSetActual++;
for (i = 0; i < argc; i++){
int j;
for (j = 0; j < sizeof (colNameTable)/sizeof(colNameTable[0]); j++) {
if (strcmp (azColName[i], colNameTable[j]) == 0) {
switch (j) {
case 0:
strncpy (pTbl1Record[iIndex].cKey, (argv[i] ? argv[i] : "NULL"), 19);
break;
case 1:
pTbl1Record[iIndex].iValue = atoi (argv[i] ? argv[i] : "0");
break;
default:
break;
}
break;
}
}
}
}
return iRetStatus;
}