我正在开发C程序,它将帮助我显示浏览器历史记录。 每当我在sqlite中运行任何sql命令时,它都会显示文件中的所有历史记录。 这就是Sql命令(包含chrome历史的历史文件)!
sqlite3历史记录"选择日期时间(last_visit_time / 1000000-11644473600,' unixepoch'),来自网址的网址由last_visit_time desc" > history_export.txt
例如,它给了我一个好结果
2017-06-28 10:20:20 | stackoverflow.com
2017-06-28 8:20:20 google.com 2017-06-28 07.10:20 | facebook.comETC
然后我希望得到与C Application相同的结果。 这是我的代码:
int main()
{
sqlite3 *db;
char *err_msg = 0;
int rc = sqlite3_open("c:/Users/XXXXXX/AppData/Local/Google/Chrome/User Data/Default/History", &db);
if (rc != SQLITE_OK) {
fprintf(stderr, "Cannot open database: %s\n",
sqlite3_errmsg(db));
sqlite3_close(db);
return 1;
}
//the same command works fine in sqlite3
char *sql = "select datetime(last_visit_time/1000000-11644473600,'unixepoch'),url from urls order by last_visit_time desc";
rc = sqlite3_exec(db, sql, callback, 0, &err_msg);
if (rc != SQLITE_OK ) {
fprintf(stderr, "Failed to select data\n");
fprintf(stderr, "SQL error: %s\n", err_msg);
sqlite3_free(err_msg);
sqlite3_close(db);
return 1;
}
sqlite3_close(db);
system ("pause");
return 0;
}
//declaration of callback function i think that the problem is here
int callback(void *NotUsed, int argc, char **argv,
char **azColName) {
NotUsed = 0;
FILE *fp ;
fp=fopen("C:/sqlite/historyc.txt","w");
for (int i = 0; i < argc; i++) {
fprintf(fp,"%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}
它显示我2或3行的旧访问(2017年3月20日..) 但是我希望得到与sql命令相同的结果。 可能问题是由回调函数引起的。
答案 0 :(得分:0)
将fopen(...,"w")
更改为fopen(...,"a+")
可以解决我的问题。这是因为您的代码每次打开文件时都会擦除文件,即每行(覆盖上一行)。 a+
将附加到现有文件而不是擦除它,因此您将获得文件中打印的所有行。每次运行程序时都需要手动删除historyc.txt,否则它将继续增长。
当然,"a+"
在这种情况下只是一个肮脏的黑客,而不是一个非常有效的黑客。另一个稍微更有效的黑客攻击是将*fp
设为全局,然后在exec
语句之前打开该文件(并从中删除*fp
和open
回调函数)。仍然很脏,但至少这意味着文件只打开一次。
...代码
#include <stdio.h>
#include <sqlite3.h>
int callback(void*, int, char**, char**);
int main(int argc, char** argv) {
sqlite3 *db;
char *err_msg = 0;
int rc = sqlite3_open("your_db_file", &db);
if (rc != SQLITE_OK) {
fprintf(stderr, "Cannot open database: %s\n",
sqlite3_errmsg(db));
sqlite3_close(db);
return 1;
}
char *sql = "select datetime(last_visit_time/1000000-11644473600,"
"'unixepoch') as visit_time,url from urls order by "
"last_visit_time desc";
rc = sqlite3_exec(db, sql, callback, 0, &err_msg);
if (rc != SQLITE_OK ) {
fprintf(stderr, "Failed to select data\n");
fprintf(stderr, "SQL error: %s\n", err_msg);
sqlite3_free(err_msg);
sqlite3_close(db);
return 0;
}
sqlite3_close(db);
return 0;
}
int callback(void *NotUsed, int argc, char **argv,
char **azColName) {
NotUsed = 0;
FILE *fp ;
// Very dirty but it works for me
fp=fopen("/tmp/historyc.txt","a+");
for (int i = 0; i < argc; i++) {
fprintf(fp,"%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
return 0;
}