Reputation: 115
I'm really new to Sqlite and I want to write a text file (xml actually) from an sqlite database table automatically using C. How can I do that? I got these to select some data from database and print in terminal:
int callback(void * ptr, int resultados, char ** STR1, char **STR2) {
int i;
for(i = 0; STR1[i] != NULL; i++) {
printf("%s = %s\n", STR2[i], STR1[i]);
}
return 0;
}
and inside of main:
/* Open database */
rc = sqlite3_open("test.db", &db);
if( rc ){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
exit(0);
}else{
fprintf(stderr, "Opened database successfully\n");
}
/* Create SQL statement */
sql = "SELECT * from COMPANY";
/* Execute SQL statement */
rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
if( rc != SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}else{
fprintf(stdout, "Operation done successfully\n");
}
sqlite3_close(db);
and then I tried to change the callback, to get STR1 and STR2 to write a text file, something like this:
int callback(void * ptr, int resultados, char ** STR1, char **STR2) {
int i;
char teste[1024];
FILE *pFile;
pFile = fopen ("test.txt", "a+");
for(i = 0; STR1[i] != NULL; i++) {
printf("%s = %s\n", STR2[i], STR1[i]);
snprintf (teste, sizeof(teste), "%s %s\n", STR2[i], STR1[i]);
fwrite (teste, 1, sizeof(teste), pFile);
fflush(pFile);
}
return 0;
}
but when I try to open the test.txt, gedit says 'There was a problem opening the file /home/kdan/test/test.txt. The file you opened has some invalid characters', and the text contains a bunch of random characters, numbers and symbols. So I'm not being able to get the selected data and convert to string D: should I try to use something like sqlite_mprintf
, sqlite_vmprintf
, sqlite_exec_printf
or sqlite_get_table_printf
? Would it be right? Or is there another way to select the data and format it to a variable char
? Sorry for my rusty english.
Edited: It is working now, just needed to use fputs instead of fwrite, here is the code working:
int callback(void * ptr, int resultados, char ** STR1, char **STR2) {
int i;
char teste[1024];
FILE *pFile;
pFile = fopen ("test.txt", "a");
for(i = 0; STR1[i] != NULL; i++) {
printf("%s = %s\n", STR2[i], STR1[i]);
snprintf (teste, sizeof(teste), "%s %s\n", STR2[i], STR1[i]);
fputs (teste, pFile);
fflush(pFile);
}
return 0;
}
Upvotes: 0
Views: 388
Reputation: 2702
Haven't tested your code but I think the problem is with the fwrite()
call.
From the linux manpages:
NAME
fread, fwrite - binary stream input/output
SYNOPSIS
[...]
size_t fwrite(const void *ptr, size_t size, size_t nmemb,
FILE *stream);
DESCRIPTION
[...]
The function fwrite() writes nmemb elements of data, each size bytes
long, to the stream pointed to by stream, obtaining them from the loca‐
tion given by ptr.
STR2[i]
and STR1[i]
may have a total length less than sizeof teste
. For illustrative purpose, let's say STR2[i]
is "foo"
and STR1[i]
is "bar"
. After the snprintf()
call, teste
will have the following contents:
teste[0] 'f'
teste[1] 'o'
teste[2] 'o'
teste[3] ' '
teste[4] 'b'
teste[5] 'a'
teste[6] 'r'
teste[7] '\n'
teste[8] '\0'
teste[9] onwards uninitialised
Since fwrite
is for writing to a binary stream, it will NOT stop writing after reaching the '\0'
byte. Instead it will keep writing all the uninitialised characters in teste
. In this case it will write 1015 uninitialised characters.
The proper way to write to a text stream is to use either fputs()
(in which case you should remove the '\n'
in your string) or fprintf()
. Or, if you really want to use fwrite()
, ask it to print strlen(teste)
bytes (which will be 8 in this case) instead of sizeof teste
which is 1024.
Finally, although not related to your problem, if you are not reading from the file you should fopen()
it with "a"
instead of "a+"
.
Upvotes: 1