如果我运行以下代码(仅显示相关部分),我将收到错误消息:"库程序不按顺序调用"。
// Open database
char *lang = "Spanish";
char *DBName = "Spanish.db";
sqlite3 *db;
int sqlret;
sqlret = sqlite3_open(DBName, &db);
if (sqlret != SQLITE_OK) {
printf("Can't open database: %s \n", sqlite3_errmsg(db));
sqlite3_close(db);
return 1;
}
// Create Table
sqlite3_stmt *stmt;
char *sqlcommand;
sqlcommand = new char;
Start(sqlcommand, lang);
printf(sqlcommand);
sqlret = sqlite3_prepare_v2(db, sqlcommand, -1, &stmt, NULL);
if (sqlret != SQLITE_OK) {
printf("Error: %s \n", sqlite3_errmsg(db));
sqlite3_close(db);
return 2;
}
开始(a,b)是以下功能:
void Start(char *command, char *language) {
sprintf(command,"CREATE TABLE IF NOT EXISTS 'Vocabulary' ( "\
"'%s' TEXT NOT NULL, ", language);
strcat(command, "'Native Language' TEXT NOT NULL, " \
"'Times Asked' INT NOT NULL, " \
"'Times Correct' INT NOT NULL, " \
"'Times Wrong' INT NOT NULL );");
}
但是,如果我没有动态定义sqlcommand但是静态(我的意思是:char * sqlcommand =" CREATE ...&#34 ;;),它可以工作。如果你帮助了我,我将不胜感激!
答案 0 :(得分:1)
sqlcommand = new char;
这为一个字符分配内存。顺便说一下,你永远不会删除。
你不想要一个字符,而是整个字符串。从技术上讲,这意味着您需要一对new[]
和delete[]
来电。但是,在C ++中,如果不必要,则不要使用原始字符串。你当然不必在这里使用它们。
改为使用std::string
!
这也允许您摆脱低级sprintf
和strcat
函数。结果如下:
std::string Start(std::string const &language)
{
return "CREATE TABLE IF NOT EXISTS 'Vocabulary' ( "\
"'" + language + "' TEXT NOT NULL, "
"'Native Language' TEXT NOT NULL, "
"'Times Asked' INT NOT NULL, "
"'Times Correct' INT NOT NULL, "
"'Times Wrong' INT NOT NULL );"
}
为了与C函数(例如SQLite API中的函数)兼容,std::string
提供c_str()
成员函数:
std::string sqlcommand = Start(lang);
sqlret = sqlite3_prepare_v2(db, sqlcommand.c_str(), -1, &stmt, NULL);
简而言之,您确实需要学习在C ++中使用字符串。你的生活将变得相当容易:)
编辑:只是提到这一点......您遇到的错误消息显然源于SQLite内部的未定义行为,因为您向它传递了一个无效的char
指针(一个不是null-terminated - 你可以在C ++中忘记的另一个C事件。)