学c语言有一阵子了。想测试一下技能。
正好单位组织安全人员考试,2300多道题,我晕,何不借此机会写一个考试机?说来就来
准备
语言 c语言
数据库 sqlite
要求
显示题目 显示选项 答错将该题放入错题库。单选30,多选20,判断30 ,随机出题
sqlite第一次用。学一学吧,用的sql语言,应该没啥大问题
我以为没有多大问题,结果问题大大的大大的。
dos命令下操作sqlite没啥大问题,用c来连接,可真是费劲了。当然你要是明白了,也就不费劲了,要是你跟我一样第一次用,好吧,费劲吧。
一开始,我以为要将sqlite.c文件等复制到工程中就可以用,结果。。。。。全是错误,而且这些错误还是莫名其妙的。。。。无语。
后来百度到了一篇有用的文章。。。花了我两天时间找到了这篇文章解决了问题。。。。(转载地址 https://www.iteye.com/blog/972169909-qq-com-1677691)
到http://www.sqlite.org/download.html下载:
解压后得到sqlite3.h,得到的其他文件这里不会用到
下载第二个,解压后得到sqlite3.dll和sqlite3.def
下面要做的是:利用sqlite3.def生成sqlite3.lib
①把sqlite3.def放到VC6的LIB.exe所在目录,例如我的VC是装在G盘的:G:\Microsoft Visual Studio\VC98\Bin
②开始菜单->运行->cmd,打开cmd命令行
(以下括号里的黑色字体是输入的内容)
③输入(g:)然后回车切换到g盘目录(因为我VC装在g盘)
④输入(cd \Microsoft Visual Studio\VC98\Bin)然后回车切换到LIB.exe所在目录
⑤输入命令(LIB /MACHINE:IX86 /DEF:sqlite3.def)然后回车,在同一目录下就会生成了sqlite3.lib文件了,当然还生成了sqlite3.exp,不过这里没用到
(如果提示丢失mspd60.dll,请到\Microsoft Visual Studio\Common\MSDev98\Bin目录找到mspd60.dll,然后再把它复制到\Microsoft Visual Studio\VC98\Bin目录)
参考截图:
⑥用VC6新建一个空的控制台工程,把(sqlite3.h、sqlite3.dll、sqlite3.lib)放到工程文件夹里,
选择菜单栏的工程-->设置:在连接的(对象/库模块)后面加上sqlite3.lib,然后点确定
通过上述,解决了问题,不报错了。但是总是提示一个问题就是 应用程序无法正常启动 搞了老半天,明明程序没问题,为什么老是无法启动呢?然后百度了一下,有位同志别的程序也出现了问题,他说是dll的版本跟系统版本不一致导致的。。。。
不可能啊,我系统64位,我在sqlite官网下的也是64位的,为啥会有问题呢?
难道是我下错了?好吧,全删了,再重新下载,然后又重新生成了一遍,结果老样子。。。。难道是让我用32位?我系统是64的啊。。。苍天啊,试一下吧,下载了32位的dll,然后生成一个32位lib,好吧,成功了,成功了,这是什么鬼。。。见鬼了啊。
。再找找原因,难道是我的vc的编译版本的问题?结果找到了
,看到了么?32位。。然后去百度了一下vc6是否支持64.。。好吧,原始版本只支持32位系统。。。。我服了,要学的东西好多啊。。。
现在基本的判断题功能已经实现,还有单选和多选,所以想单独拿出来做方法,这样代码看起来更调理,可是。。。不幸的事情发生了

,错误原因 error C2371: 'Panduanti' : redefinition; different basic types。
无奈之际,自己试错,是需要在程序头部加方法的定义。。。但是我以前的方法都没有加定义运行没问题,为什么单独拿出来就有问题呢?这个问题以后再仔细研究,先把程序写完
char *p = " hello world "; 和 char p[ ] = " hello world ! ";
所有的字符串常量存放在静态存储区。【字符串常量是贯穿整个程序的生命周期的】,所以1,2只是是否能够访问到的问题,
1. 字符串常量的地址赋值给指针常量,改指针常量指向的字符串的字符不允许修改。不同的字符串指针指向同一个字符串时候,所有的指针指向同一个地址。
2. 将字符串的每个字符赋值给数组,该指针指向数组的首地址,
在 char p [ ] = "heloo "; 中, ” hello “ 是一个字符串常量,存放在静态数据区,但是把一个字符串常量赋值给了一个局部变量(char p [ ] 型数组),该局部变量是存放在栈中的。这样子就有两块内容一样的内存,意思就是说 : char p [ ] = :hello : 这条语句让 ”hello“ 在内存中有两条拷贝,一份在动态分布的栈中,一份在静态存储区。而char *p = ''hello '' 第二个是指向静态存储区的指针,此变量指向的内存在程序运行中不会被清空。
作者:少年英雄房飞冯
链接:https://www.jianshu.com/p/b5c49b747fbf
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
#include <stdio.h> #include <stdlib.h> #include "sqlite3.h" #include "strParse.h" #define DB_NAME "anquanc.db" #define DANXUAN_NAME "aaa.csv" #define DUOXUAN_NAME "bbb.csv" #define PANDUANXUAN_NAME "ccc.csv" void printPanduan(char *ta,char *id,char *type); void panduanTi(FILE *fp,char *p); void danxuanTi(FILE *fp,char *p); void duoxuanTi(FILE *fp,char *p); void printPanduan(char *ta); sqlite3 *conn = NULL; char *err_msg = NULL; char *sqlT; char sql[2000] = ""; /*bool skip(){ scanf("%*[A-E]"); return true; }*/ int sqlite3_exec_callback (void *data, int nColumn, char **colValues, char **colNames) { int i; char *answerA; char *answerB; char *answerC; char *answerD; char *answerE; char *trueAnswer; char *type; char *id; // printf("%d\n",nColumn); for ( i = 0; i < nColumn; i++) { switch(i) { case 0: id=colValues[i]; // printf("id:%s\t",colValues[i]); break; case 1: printf ("%s\t\n", colValues[i]); break; case 2: answerA=colValues[i]; break; case 3: answerB=colValues[i]; break; case 4: answerC=colValues[i]; break; case 5: answerD=colValues[i]; break; case 6: answerE=colValues[i]; break; case 7: trueAnswer=colValues[i]; break; case 8: type=colValues[i]; break; default: //type=colValues[i]; //printf("%s",type); break; } } if(strcmp(type,"1")==0) { printf ("%s\t\n", colValues[2]); printf ("%s\t\n", colValues[3]); printf ("%s\t\n", colValues[4]); printf ("%s\t\n", colValues[5]); printPanduan(trueAnswer,id,type); } if(strcmp(type,"2")==0) { printf ("%s\t\n", colValues[2]); printf ("%s\t\n", colValues[3]); printf ("%s\t\n", colValues[4]); printf ("%s\t\n", colValues[5]); printf ("%s\t\n", colValues[6]); printPanduan(trueAnswer,id,type); } if(strcmp(type,"3")==0) { printPanduan(trueAnswer,id,type); } printf ("\n"); return 0; } void panduanTi(FILE *fp,char *p) { char text[2400][400]; char *ques; char *ans; char *pd="o"; char Aanswer='A'; char Banswer='B'; char Canswer='C'; char Danswer='D'; int i=0; int j=0; while(fp!=NULL && i<2000 && !feof(fp)) { fscanf(fp,"%s",&text[i]); if(strstr(text[i],p)) { // printf("baohan\n"); i++; } else { if(i!=0 && !strstr(text[i-1],p)) strcat(text[i-1], text[i]); else i++; // printf("bubaohan\n"); } if(feof(fp)) { //printf("wenjianjieshu"); strcat(text[i], pd); } // fscanf(fp,"%s",text1); // fseek(fp,2L,SEEK_CUR); // printf("%d\n",i); } for(j=0;j<i;j++) { if(!strstr(text[j],p)) { ques=text[j]; ans=text[j+1]; // printf("11111%s\n",text[i]); } // printf("%s",ques); sprintf (sql, "INSERT INTO test (question, trueAnswer, questionType) VALUES ('%s', '%s', %c)", ques, ans, '3'); if (sqlite3_exec (conn, sql, NULL, NULL, &err_msg) != SQLITE_OK) { printf ("操作失败,错误代码:%s\n", err_msg); exit(-1); } j++; // printf("%s\n",text[i]); // printf("%d\n",i); } } void printPanduan(char *ta,char *id,char *type) { char str,ctr[5],*actr; if(strchr(type,'1')) { do{ printf("单选题:请输入答案,以回车结束\n"); scanf("%c", &str); str=toUper(str); while(getchar() != '\n'); } while(str<'A'||str>'D' || str =='0'); if(strchr(ta,str)) { printf("回答正确\n"); sprintf (sql, "update test set AnswerRight=1 where id=%s",id); if (sqlite3_exec (conn, sql, NULL, NULL, &err_msg) != SQLITE_OK) { // printf(sql); printf ("操作失败,错误代码:%s\n", err_msg); exit(-1); } } else { printf("回答错误\n"); } } else if(strchr(type,'2')) { printf("多选题:请输入答案 以回车结束\n"); while (scanf("%[A-E]%[A-E]%[A-E]%[A-E]%[A-E]", &ctr) != 1) { while(getchar() != '\n'); printf("输入错误,请输入A,B,C,D,E\n"); } // scanf("%[A-E],%[A-E],%[A-E],%[A-E],%[A-E]",&ctr); //不是A-Z就结束 if(getEnglish(ta,ctr)==0) { printf("回答正确\n"); sprintf (sql, "update test set AnswerRight=1 where id=%s",id); if (sqlite3_exec (conn, sql, NULL, NULL, &err_msg) != SQLITE_OK) { //printf(sql); printf ("操作失败,错误代码:%s\n", err_msg); exit(-1); } } else { printf("回答错误\n"); } } else { do{ printf("判断题:请输入答案 正确输入A错误输入B,以回车结束\n"); scanf("%c", &str); str=toUper(str); while(getchar() != '\n'); } while(str!='a' &&str!='b'&&str!='A' &&str!='B'); if(strchr(ta,str)) { printf("回答正确\n"); sprintf (sql, "update test set AnswerRight=1 where id=%s",id); if (sqlite3_exec (conn, sql, NULL, NULL, &err_msg) != SQLITE_OK) { //printf(sql); printf ("操作失败,错误代码:%s\n", err_msg); exit(-1); } } else { printf("回答错误\n"); } } // printf(strchr(trueAnswer,str)); } //读取excel写入数据库 void getExcel(char fileName[10]) { // char *p="正确答案"; // system("chcp 65001"); FILE *filepipe=fopen(fileName,"r"); fseek(filepipe,0L,SEEK_SET); // Panduan(filepipe); if(strstr(fileName,DANXUAN_NAME)) { danxuanTi(filepipe,p); } else if(strstr(fileName,DUOXUAN_NAME)) { duoxuanTi(filepipe,p); } else { panduanTi(filepipe,p); } // printf("%s",text1); } char* intArrayPriseStr(int array[100]) { int i; char str[1000]={'\0'}; char pstr[1000]={'\0'}; for(i=0;i<100;i++) { sprintf(pstr,"%d",array[i]); strcat(str,pstr); if(i<99) strcat(str,","); } //printf("%s\n",str); return str; } void duoxuanTi(FILE *fp,char *p) { char getCell[400]; char answerA[400]; char answerB[400]; char answerC[400]; char answerD[400]; char answerE[400]; char ques[400]; char ans[400]; char Aanswer='A'; char Banswer='B'; char Canswer='C'; char Danswer='D'; char Eanswer='E'; int i=0; int j=0; while(fp!=NULL && !feof(fp)) { fscanf(fp,"%s",&getCell); if(strstr(getCell,p)) { // printf("baohan\n"); strcpy(ans, getCell); //ans=getCell; i=0; } else if(strchr(getCell,Aanswer)) { strcpy(answerA, getCell); i=2; } else if(strchr(getCell,Banswer)) { strcpy(answerB, getCell); i=3; } else if(strchr(getCell,Canswer)) { strcpy(answerC, getCell); i=4; } else if(strchr(getCell,Danswer)) { strcpy(answerD, getCell); i=5; } else if(strchr(getCell,Eanswer)) { strcpy(answerE, getCell); i=6; } else { if(i>0) { switch(i) { case 2: strcat(answerA, getCell); break; case 3: strcat(answerB, getCell); break; case 4: strcat(answerC, getCell); break; case 5: strcat(answerD, getCell); break; case 6: strcat(answerE, getCell); break; default: strcat(ques, getCell); break; } } else { strcpy(ques, getCell); i=1; } } // sprintf (sql, "INSERT INTO test (question, trueAnswer, questionType) VALUES ('%s', '%s', %c)", ques, ans, '1'); if(i==0) {sprintf (sql, "INSERT INTO test (question,answerA,answerB,answerC,answerD,answerE, trueAnswer, questionType) VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', %c)", ques, answerA,answerB,answerC,answerD,answerE,ans, '2'); if (sqlite3_exec (conn, sql, NULL, NULL, &err_msg) != SQLITE_OK) { // printf(sql); printf ("操作失败,错误代码:%s\n", err_msg); exit(-1); } j++; printf("%d",j); } } } void danxuanTi(FILE *fp,char *p) { char getCell[400]; char answerA[400]; char answerB[400]; char answerC[400]; char answerD[400]; char ques[400]; char ans[400]; char Aanswer='A'; char Banswer='B'; char Canswer='C'; char Danswer='D'; int i=0; int j=0; while(fp!=NULL && !feof(fp)) { fscanf(fp,"%s",&getCell); if(strstr(getCell,p)) { // printf("baohan\n"); strcpy(ans, getCell); //ans=getCell; i=0; } else if(strchr(getCell,Aanswer)) { strcpy(answerA, getCell); i=2; } else if(strchr(getCell,Banswer)) { strcpy(answerB, getCell); i=3; } else if(strchr(getCell,Canswer)) { strcpy(answerC, getCell); i=4; } else if(strchr(getCell,Danswer)) { strcpy(answerD, getCell); i=5; } else { if(i>0) { switch(i) { case 2: strcat(answerA, getCell); break; case 3: strcat(answerB, getCell); break; case 4: strcat(answerC, getCell); break; case 5: strcat(answerD, getCell); break; default: strcat(ques, getCell); break; } } else { strcpy(ques, getCell); i=1; } } // sprintf (sql, "INSERT INTO test (question, trueAnswer, questionType) VALUES ('%s', '%s', %c)", ques, ans, '1'); if(i==0) {sprintf (sql, "INSERT INTO test (question,answerA,answerB,answerC,answerD, trueAnswer, questionType) VALUES ('%s', '%s', '%s', '%s', '%s', '%s', %c)", ques, answerA,answerB,answerC,answerD,ans, '1'); if (sqlite3_exec (conn, sql, NULL, NULL, &err_msg) != SQLITE_OK) { // printf(sql); printf ("操作失败,错误代码:%s\n", err_msg); exit(-1); } j++; printf("%d",j); } } } int main() { int a[100]; char excelOrAnswer; char *randnumber; int i;srand(time(0)); /*初始化种子*/ for( i = 0; i < 100; i++ ) { a[i]=rand()%2301; //printf("%d\n",a[i]); } //打开数据库,创建连接 if (sqlite3_open(DB_NAME, &conn) != SQLITE_OK) puts ("无法打开!"); printf("请选择操作:A 导入单选题 B 进行答题 C 导入多选题 D 导入判断题 \n"); scanf("%c",&excelOrAnswer); excelOrAnswer=toLower(excelOrAnswer); while(getchar() != '\n'); if('a'==excelOrAnswer) { //printf("单选"); getExcel(DANXUAN_NAME); } if('c'==excelOrAnswer) { //printf("多选"); getExcel(DUOXUAN_NAME); } if('d'==excelOrAnswer) { //printf("判断"); getExcel(PANDUANXUAN_NAME); } if('b'==excelOrAnswer) { //查询 randnumber=intArrayPriseStr(a); strcpy(sql, "SELECT * FROM test where ANSWERRIGHT=0 and id in ("); strncat(sql, randnumber,1000); strncat(sql, ")",10); // printf(sql); if (sqlite3_exec (conn, sql, &sqlite3_exec_callback, 0, &err_msg) != SQLITE_OK) { printf ("操作失败,错误代码:%s\n", err_msg); // exit(-1); } } //关闭连接 if (sqlite3_close(conn) != SQLITE_OK) { printf ("无法关闭,错误代码:%s\n", sqlite3_errmsg(conn)); exit(-1); } puts ("操作成功"); scanf("%s",&excelOrAnswer); return 0; }
调用了sqlite3.dll,就不提了,上面都有介绍
处理字符串的头文件
int getEnglish(char *p,char *ctr); char toLower(char a); char toUper(char a); char* toUpestrr(char a[5]);
字符串处理程序 主要是大小写 还有截断提取英文字符
char toLower(char a) { if (a >= 'A' && a <= 'Z') { a = a + 32; //大写转小写 // printf("%c", a); } else if (a >= 'a' && a <= 'z') { // a = a - 32; //小写转大写 // printf("%c", a); } else { printf("输入错误\n"); a='0'; } return a; } char toUper(char a) { if (a >= 'A' && a <= 'Z') { // a = a + 32; //大写转小写 // printf("%c", a); } else if (a >= 'a' && a <= 'z') { a = a - 32; //小写转大写 // printf("%c", a); } else { printf("输入错误\n"); a='0'; } return a; } char* toUpestrr(char a[5]) { int i; for(i=0;i<5;i++) { a[i]=toUper(a[i]); } return a; } int getEnglish(char *p,char *ctr) { char str[6]; int j=0,inx,x; int limit = strlen(p); for (inx=0;inx!=limit; ++inx) { if('A'<=p[inx]&&p[inx]<='Z') { str[j]=p[inx]; j++; } } // x=strcmp(str,ctr); // printf("%d",x); str[j]='\0'; return strcmp(str,ctr); }
小程序告一段落。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix