您好,我对此功能recup()
有疑问。 recup()
的目的是将在字符串chaine
中找到的所有单词逐字地插入数据库。这些单词来自用户使用fgets设置的chaine。我面临的问题是,它仅插入与chaine
的第一个单词相同长度的单词。
例如,如果我写“我想要一只猫”,则只会插入“ I”和“ a”。
int recup(char *chaine){
char tab[30] ={0};
char delim[] = " ";
char *ptr = strtok(chaine,delim);
int rc =0;
char *sql ="INSERT INTO newTable SELECT * FROM dbTable where lemme =?";
sqlite3_stmt *stmt = 0;
rc = sqlite3_prepare_v2(db,sql,-1,&stmt,0);
do {
// Expected word is printed here
printf("%s\n",ptr);
strcpy(tab,ptr);
// For some reason, only words that match the length
// of the first word are being inserted
rc = sqlite3_bind_text(stmt,1,tab,-1,SQLITE_STATIC);
rc = sqlite3_step(stmt);
ptr = strtok(NULL,delim);
} while(ptr != NULL);
rc = sqlite3_finalize(stmt);
return 0;
}
#include <ansi_c.h>
#include <sqlite3.h>
#include "fdata.h"
sqlite3 *db;
int main(int argc, char* argv[]) {
int rc = 0;
char chaine[100] = {0};
rc = sqlite3_open("lexique.db",&db);
check(rc);
createNewT();
question(&chaine);
recup(&chaine);
sqlite3_close(db);
return 0;
}
答案 0 :(得分:1)
这是mcve,显示了如何使用strtok
来标记示例字符串:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
char *test = "I want a cat";
char chaime[strlen(test) + 1];
char *delim = " ";
char *ptr = NULL;
strcpy(chaime, test);
ptr = strtok(chaime, delim);
while (ptr) {
printf("%s\n", ptr);
ptr = strtok(NULL, delim);
}
return 0;
}
输出
[user@machine]: ./program
I
want
a
cat
注意
如果您能给我们这样的东西来证明您的问题,那么它将很容易为您提供帮助。
答案 1 :(得分:1)
strtok()函数修改传递给它的字符串。因此,有必要创建输入字符串的副本。请参阅@David Cullen的出色答案,该答案创建了mcve。
请参阅更正后的代码中的注释,以解释正在发生的事情。
#include <stdio.h>
#include <string.h>
int recup(char *chaine){
char tab[30] ={0};
char delim[] = " ";
///// strtok will modify its inut string argument, so create a copy of the input
strcpy(tab, chaine);
// ptr will contain the current last token that was parsed
char *ptr = strtok(tab,delim); // pass the copy to strtok, ptr points to first word
int rc =0;
char *sql ="INSERT INTO newTable SELECT * FROM dbTable where lemme =?";
sqlite3_stmt *stmt = 0;
rc = sqlite3_prepare_v2(db,sql,-1,&stmt,0);
while (ptr) {
printf("%s\n",ptr); // print the word that was just tokenized
rc = sqlite3_bind_text(stmt,1,ptr,-1,SQLITE_STATIC);
rc = sqlite3_step(stmt);
ptr = strtok(NULL,delim);
}
rc = sqlite3_finalize(stmt);
return 0;
}
答案 2 :(得分:1)
C SQLite API不太宽容,并且需要严格的语义。在这里,您的问题是您尝试在循环中重用SQL语句(正确)而不重置(错误)。当前流为:
sqlite3_open
sqlite3_prepare_v2
sqlite3_bind
sqlite3_step
sqlite3_bind => ERROR SQLITE_MISUSE
sqlite3_step
的文档中说(强调我的):
SQLITE_DONE表示该语句已成功完成执行。在未首先调用sqlite3_reset()来将虚拟机重置回其初始状态之前,不应在此虚拟机上再次调用 sqlite3_step()。
我认为以下sqlite3_step
会导致语句重置,这将允许处理第三个单词,但您每第二个单词都会丢失。
循环应为:
do {
printf("%s\n",ptr);
strcpy(tab,ptr);
rc = sqlite3_bind_text(stmt,1,tab,-1,SQLITE_STATIC);
if (rc) {
// process error
}
rc = sqlite3_step(stmt);
if (rc != SQLITE_DONE) {
// process error
}
sqlite3_reset(stmt);
ptr = strtok(NULL,delim);
} while(ptr);