Sqlite3 C++ 使用方法

2023-11-09

需要在 C++ 程序中读写 sqlite3 数据库,查阅了一下资料,发现了一个简单实用教程。另外还有如何在windows下生成sqlite3静态库,生成好的sqlite3静态库可以在这里下载。


windows下生成sqlite3静态库

  1. 去 sqlite 官网下载页面下载源文件 sqlite-amalgamation-3180000.zip 。
  2. 在VS2013中,文件->新建->项目->Win32项目,命名为sqlite3(其他名称也行)。在向导设置中,选择DLL(D)、空项目。选择release x64模式。
  3. 将下载的sqlite-amalgamation-3180000.zip 中的“sqlite3.h”、“sqlite3.c”、“sqlite3ext.h”三个文件添加到工程中,具体做法:右键sqlite3工程->添加->现有项,在出现的对话框中选择上述三个文件。
  4. 编译生成sqlite3.dll文件,同时会在工程所在目录中产生sqlite3.obj文件。
  5. 接下来要用到VS安装目录下的lib.exe文件。将sqlite3.obj文件复制到lib.exe所在目录下,我的是C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\amd64。
  6. 打开cmd窗口,转到lib.exe所在文件夹下。输入命令:lib sqlite3.obj。这时会生成静态的sqlite3.lib(大小为2.91MB)如果无法生成,可以试试用管理员权限运行cmd。
  7. 将sqlite3.lib和sqlite3.h添加到VS工程就可以使用sqlite啦。

SQLite C/C++ Tutorial

C/C++ Interface APIs

介绍三个主要的 API,知道这三个API就可以简单的使用sqlite3了。原tutotial写得非常清楚,我直接复制过来了。

  1. sqlite3_open(const char *filename, sqlite3 **ppDb)

    This routine opens a connection to an SQLite database file and returns a database connection object to be used by other SQLite routines.

    If the filename argument is NULL or ‘:memory:’, sqlite3_open() will create an in-memory database in RAM that lasts only for the duration of the session.

    If filename is not NULL, sqlite3_open() attempts to open the database file by using its value. If no file by that name exists, sqlite3_open() will open a new database file by that name.

  2. sqlite3_exec(sqlite3*, const char *sql, sqlite_callback, void *data, char **errmsg)

    This routine provides a quick, easy way to execute SQL commands provided by sql argument which can consist of more than one SQL command.

    Here, first argument sqlite3 is open database object, sqlite_callback is a call back for which data is the 1st argument and errmsg will be return to capture any error raised by the routine.

  3. sqlite3_close(sqlite3*)

    This routine closes a database connection previously opened by a call to sqlite3_open(). All prepared statements associated with the connection should be finalized prior to closing the connection.

    If any queries remain that have not been finalized, sqlite3_close() will return SQLITE_BUSY with the error message Unable to close due to unfinalized statements.


Connecting To Database

Following C code segment shows how to connect to an existing database. If database does not exist, then it will be created and finally a database object will be returned.

#include <stdio.h>
#include <sqlite3.h> 

int main(int argc, char* argv[])
{
   sqlite3 *db;
   char *zErrMsg = 0;
   int rc;

   rc = sqlite3_open("test.db", &db);

   if( rc ){
      fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
      return(0);
   }else{
      fprintf(stderr, "Opened database successfully\n");
   }
   sqlite3_close(db);
}

Now, let’s compile and run above program to create our database test.db in the current directory. You can change your path as per your requirement.

$gcc test.c -l sqlite3
$./a.out
Opened database successfully

If you are going to use C++ source code, then you can compile your code as follows:

$g++ test.c -l sqlite3

Here we are linking our program with sqlite3 library to provide required functions to C program. This will create a database file test.db in your directory and you will have the result something as follows:

-rwxr-xr-x. 1 root root 7383 May 8 02:06 a.out
-rw-r–r–. 1 root root 323 May 8 02:05 test.c
-rw-r–r–. 1 root root 0 May 8 02:06 test.db


Create a Table

Following C code segment will be used to create a table in previously created database:

#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h> 

static int callback(void *NotUsed, int argc, char **argv, char **azColName){
   int i;
   for(i=0; i<argc; i++){
      printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
   }
   printf("\n");
   return 0;
}

int main(int argc, char* argv[])
{
   sqlite3 *db;
   char *zErrMsg = 0;
   int  rc;
   char *sql;

   /* Open database */
   rc = sqlite3_open("test.db", &db);
   if( rc ){
      fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
      return(0);
   }else{
      fprintf(stdout, "Opened database successfully\n");
   }

   /* Create SQL statement */
   sql = "CREATE TABLE COMPANY("  \
         "ID INT PRIMARY KEY     NOT NULL," \
         "NAME           TEXT    NOT NULL," \
         "AGE            INT     NOT NULL," \
         "ADDRESS        CHAR(50)," \
         "SALARY         REAL );";

   /* Execute SQL statement */
   rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
   if( rc != SQLITE_OK ){
   fprintf(stderr, "SQL error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
   }else{
      fprintf(stdout, "Table created successfully\n");
   }
   sqlite3_close(db);
   return 0;
}

When above program is compiled and executed, it will create COMPANY table in your test.db and final listing of the file will be as follows:

-rwxr-xr-x. 1 root root 9567 May 8 02:31 a.out
-rw-r–r–. 1 root root 1207 May 8 02:31 test.c
-rw-r–r–. 1 root root 3072 May 8 02:31 test.db


INSERT Operation

Following C code segment shows how we can create records in our COMPANY table created in above example:

#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h> 

static int callback(void *NotUsed, int argc, char **argv, char **azColName){
   int i;
   for(i=0; i<argc; i++){
      printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
   }
   printf("\n");
   return 0;
}

int main(int argc, char* argv[])
{
   sqlite3 *db;
   char *zErrMsg = 0;
   int rc;
   char *sql;

   /* Open database */
   rc = sqlite3_open("test.db", &db);
   if( rc ){
      fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
      return(0);
   }else{
      fprintf(stderr, "Opened database successfully\n");
   }

   /* Create SQL statement */
   sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "  \
         "VALUES (1, 'Paul', 32, 'California', 20000.00 ); " \
         "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "  \
         "VALUES (2, 'Allen', 25, 'Texas', 15000.00 ); "     \
         "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)" \
         "VALUES (3, 'Teddy', 23, 'Norway', 20000.00 );" \
         "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)" \
         "VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 );";

   /* Execute SQL statement */
   rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
   if( rc != SQLITE_OK ){
      fprintf(stderr, "SQL error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
   }else{
      fprintf(stdout, "Records created successfully\n");
   }
   sqlite3_close(db);
   return 0;
}

When above program is compiled and executed, it will create given records in COMPANY table and will display following two line:

Opened database successfully
Records created successfully


SELECT Operation

Before we proceed with actual example to fetch records, let me give a little detail about the callback function, which we are using in our examples. This callback provides a way to obtain results from SELECT statements. It has the following declaration:

typedef int (*sqlite3_callback)(
void*,    /* Data provided in the 4th argument of sqlite3_exec() */
int,      /* The number of columns in row */
char**,   /* An array of strings representing fields in the row */
char**    /* An array of strings representing column names */
);

If above callback is provided in sqlite_exec() routine as the third argument, SQLite will call the this callback function for each record processed in each SELECT statement executed within the SQL argument.

Following C code segment shows how we can fetch and display records from our COMPANY table created in above example:

#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h> 

static int callback(void *data, int argc, char **argv, char **azColName){
   int i;
   fprintf(stderr, "%s: ", (const char*)data);
   for(i=0; i<argc; i++){
      printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
   }
   printf("\n");
   return 0;
}

int main(int argc, char* argv[])
{
   sqlite3 *db;
   char *zErrMsg = 0;
   int rc;
   char *sql;
   const char* data = "Callback function called";

   /* Open database */
   rc = sqlite3_open("test.db", &db);
   if( rc ){
      fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
      return(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);
   return 0;
}

When above program is compiled and executed, it will produce the following result:

Opened database successfully
Callback function called: ID = 1
NAME = Paul
AGE = 32
ADDRESS = California
SALARY = 20000.0

Callback function called: ID = 2
NAME = Allen
AGE = 25
ADDRESS = Texas
SALARY = 15000.0

Callback function called: ID = 3
NAME = Teddy
AGE = 23
ADDRESS = Norway
SALARY = 20000.0

Callback function called: ID = 4
NAME = Mark
AGE = 25
ADDRESS = Rich-Mond
SALARY = 65000.0

Operation done successfully


UPDATE Operation

Following C code segment shows how we can use UPDATE statement to update any record and then fetch and display updated records from our COMPANY table:

#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h> 

static int callback(void *data, int argc, char **argv, char **azColName){
   int i;
   fprintf(stderr, "%s: ", (const char*)data);
   for(i=0; i<argc; i++){
      printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
   }
   printf("\n");
   return 0;
}

int main(int argc, char* argv[])
{
   sqlite3 *db;
   char *zErrMsg = 0;
   int rc;
   char *sql;
   const char* data = "Callback function called";

   /* Open database */
   rc = sqlite3_open("test.db", &db);
   if( rc ){
      fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
      return(0);
   }else{
      fprintf(stderr, "Opened database successfully\n");
   }

   /* Create merged SQL statement */
   sql = "UPDATE COMPANY set SALARY = 25000.00 where ID=1; " \
         "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);
   return 0;
}

When above program is compiled and executed, it will produce the following result:

Opened database successfully
Callback function called: ID = 1
NAME = Paul
AGE = 32
ADDRESS = California
SALARY = 25000.0

Callback function called: ID = 2
NAME = Allen
AGE = 25
ADDRESS = Texas
SALARY = 15000.0

Callback function called: ID = 3
NAME = Teddy
AGE = 23
ADDRESS = Norway
SALARY = 20000.0

Callback function called: ID = 4
NAME = Mark
AGE = 25
ADDRESS = Rich-Mond
SALARY = 65000.0

Operation done successfully


DELETE Operation

Following C code segment shows how we can use DELETE statement to delete any record and then fetch and display remaining records from our COMPANY table:

#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h> 

static int callback(void *data, int argc, char **argv, char **azColName){
   int i;
   fprintf(stderr, "%s: ", (const char*)data);
   for(i=0; i<argc; i++){
      printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
   }
   printf("\n");
   return 0;
}

int main(int argc, char* argv[])
{
   sqlite3 *db;
   char *zErrMsg = 0;
   int rc;
   char *sql;
   const char* data = "Callback function called";

   /* Open database */
   rc = sqlite3_open("test.db", &db);
   if( rc ){
      fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
      return(0);
   }else{
      fprintf(stderr, "Opened database successfully\n");
   }

   /* Create merged SQL statement */
   sql = "DELETE from COMPANY where ID=2; " \
         "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);
   return 0;
}

When above program is compiled and executed, it will produce the following result:

Opened database successfully
Callback function called: ID = 1
NAME = Paul
AGE = 32
ADDRESS = California
SALARY = 20000.0

Callback function called: ID = 3
NAME = Teddy
AGE = 23
ADDRESS = Norway
SALARY = 20000.0

Callback function called: ID = 4
NAME = Mark
AGE = 25
ADDRESS = Rich-Mond
SALARY = 65000.0

Operation done successfully


Reference

  1. http://www.cnblogs.com/imoon/archive/2012/11/30/2796726.html
  2. https://www.tutorialspoint.com/sqlite/sqlite_c_cpp.htm
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Sqlite3 C++ 使用方法 的相关文章

  • 添加对共享类的多个 WCF 服务的服务引用

    我正在尝试将我的 WCF Web 服务拆分为几个服务 而不是一个巨大的服务 但是 Visual Studio Silverlight 客户端 复制了两个服务共享的公共类 这是一个简单的例子来说明我的问题 在此示例中 有两个服务 两者都返回类
  • 获取两个字符串之间的公共部分c# [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我需要的是获取两个单词之间的共同部分并获取差异 例子 场景1 word1 感言 word2 Test 将返回 公共部分Test 不同之
  • 捕获 foreach 条件中抛出的异常

    我有一个foreach在 foreach 本身的条件下循环期间中断的循环 有没有办法try catch抛出异常然后继续循环的项 这将运行几次 直到异常发生然后结束 try foreach b in bees exception is in
  • Blazor 与 Razor

    随着 Blazor 的发明 我想知道这两种语言之间是否存在显着的效率 无论是在代码创建方面还是在代码的实际编译 执行方面 https github com SteveSanderson Blazor https github com Ste
  • 在 Xcode4 中使用 Boost

    有人设置 C Xcode4 项目来使用 Boost 吗 对于一个简单的 C 控制台应用程序 我需要在 Xcode 中设置哪些设置 Thanks 用这个来管理它 和这个
  • std::map 和二叉搜索树

    我读过 std map 是使用二叉搜索树数据结构实现的 BST 是一种顺序数据结构 类似于数组中的元素 它将元素存储在 BST 节点中并按其顺序维护元素 例如如果元素小于节点 则将其存储在节点的左侧 如果元素大于节点 则将其存储在节点的右侧
  • 为什么 BOOST_FOREACH 不完全等同于手工编码的?

    From 增强文档 http www boost org doc libs 1 48 0 doc html foreach html foreach introduction what is literal boost foreach li
  • 为什么密码错误会导致“填充无效且无法删除”?

    我需要一些简单的字符串加密 所以我编写了以下代码 有很多 灵感 来自here http www codeproject com KB security DotNetCrypto aspx create and initialize a cr
  • 如何用 kevent() 替换 select() 以获得更高的性能?

    来自Kqueue 维基百科页面 http en wikipedia org wiki Kqueue Kqueue 在内核和用户空间之间提供高效的输入和输出事件管道 因此 可以修改事件过滤器以及接收待处理事件 同时每次主事件循环迭代仅使用对
  • Xamarin Android:获取内存中的所有进程

    有没有办法读取所有进程 而不仅仅是正在运行的进程 如果我对 Android 的理解正确的话 一次只有一个进程在运行 其他所有进程都被冻结 后台进程被忽略 您可以使用以下代码片段获取当前正在运行的所有 Android 应用程序进程 Activ
  • 通过不同 DLL 或 EXE 中的指针或引用访问 STL 对象时发生访问冲突

    我在使用旧版 VC6 时遇到以下问题 我只是无法切换到现代编译器 因为我正在处理遗留代码库 http support microsoft com kb 172396 http support microsoft com kb 172396
  • 用于从字符串安全转换的辅助函数

    回到 VB6 我编写了一些函数 让我在编码时无需关心字符串的 null 和 数字的 null 和 0 等之间的区别 编码时 没有什么比添加特殊情况更能降低我的工作效率了用于处理可能导致一些不相关错误的数据的代码 9999 10000 如果我
  • C# using 语句、SQL 和 SqlConnection

    使用 using 语句 C SQL 可以吗 private static void CreateCommand string queryString string connectionString using SqlConnection c
  • gdb查找行号的内存地址

    假设我已将 gdb 附加到一个进程 并且在其内存布局中有一个文件和行号 我想要其内存地址 如何获取文件x中第n行的内存地址 这是在 Linux x86 上 gdb info line test c 56 Line 56 of test c
  • 运行代码首先迁移更新数据库时出错

    我在迁移到数据库时遇到问题 并且似乎找不到我遇到的错误的答案 System MissingMethodException Method not found System Data Entity Migrations Builders Tab
  • 以编程方式使用自定义元素创建网格

    我正在尝试以编程方式创建一个网格 并将自定义控件作为子项附加到网格中 作为 2x2 矩阵中的第 0 行第 0 列 为了让事情变得更棘手 我使用了 MVVM 设计模式 下面是一些代码可以帮助大家理解这个想法 应用程序 xaml cs base
  • 从类模板参数为 asm 生成唯一的字符串文字

    我有一个非常特殊的情况 我需要为类模板中声明的变量生成唯一的汇编程序名称 我需要该名称对于类模板的每个实例都是唯一的 并且我需要将其传递给asm关键字 see here https gcc gnu org onlinedocs gcc 12
  • 如何确定母版页中正在显示哪个子页?

    我正在母版页上编写代码 我需要知道正在显示哪个子 内容 页面 我怎样才能以编程方式做到这一点 我用这个 string pageName this ContentPlaceHolder1 Page GetType FullName 它以 AS
  • WPF/数据集:如何通过 XAML 将相关表中的数据绑定到数据网格列中?

    我正在使用 WPF DataSet 连接到 SQL Server Express XAML 和 C Visual Studio 2013 Express 我从名为 BankNoteBook 的现有 SQL Server Express 数据
  • 如何使用 std::array 模拟 C 数组初始化“int arr[] = { e1, e2, e3, ... }”行为?

    注意 这个问题是关于不必指定元素数量并且仍然允许直接初始化嵌套类型 这个问题 https stackoverflow com questions 6111565 now that we have stdarray what uses are

随机推荐

  • 一阶数字低通滤波器的实现

    1 1 计算公式推导 一阶惯性滤波算法起源于一阶低通滤波电路 在电路设计中 用于吸收和消除叠加在低频信号源上的高频干扰成份十分有效 如图1所示 激励源 通过一个由电阻R和电容器C组成充 放电回路 并以电容两端的电压作为输出 构成了基本的一阶
  • 【转】那些年使用过MapReduce的论文

    MapReduce is a programming model for processing large data sets with a parallel distributed algorithm on a cluster It s
  • pthread_attr_init线程属性

    1 线程属性 线程具有属性 用pthread attr t表示 在对该结构进行处理之前必须进行初始化 在使用后需要对其去除初始化 我们用pthread attr init函数对其初始化 用pthread attr destroy对其去除初始
  • ArcGIS Server for javascript构建自己的GraphicsLayer

    ArcGIS Server for javascript构建自己的GraphicsLayer 提起GraphicLayer就不得不说说Graphic GraphicLayer是一个包含多个Graphic的容器 而Graphic则是一个包含了
  • 若依ztree树表实现

    API Document zTree jQuery tree plug ins 以上是tree结构的推荐学习网站 问题的起源是当时刚接需求的时候需要实现树表 在初次接触时确实出现了一些问题 用了些时间才弄出来 不是驴不走就是磨不转 所以分享
  • Automa一个自动帮我完成浏览器操作,太棒了

    Automa 是一个免费 开源的 Chrome 扩展 它通过目前流行的 No Code 无代码方式 只需要拖拽模块就实现了浏览器自动化 比如自动填写表格 执行重复性任务 在工作中 如果我们遇到重复性工作 或者说是浏览器自动完成的一些操作 我
  • 单片机攻城之LeetCode刷题-704. 二分查找

    今天刷的LeetCode编程题目是704 二分查找 以下是学习笔记 二分查找算法详解 在升序数组nums 中寻找目标值target 对于特定下标i 比较nums i 和 target 的大小 1 如果nums i target 则下标i即为
  • 日语五十音图(带图)

    前言 日语的每个假名代表一个音节 拗音除外 所以属于音节字母 日语的假名共有七十一个 包括清音 浊音 半浊音和拨音 其中表示四十五个清音音节的假名 按照发音规律 可排列成表 这个假名表称为五十音图 五十音図 正文 清音 a i u e o
  • C#类(Class)的使用

    class类型是引用类型 创建类对象时 会在堆区为该对象分配内存 所分配的内存会由垃圾回收器 GC 自动管理 无需手动释放 1 声明类 我们使用class关键字来声明类 语法 访问修饰词 public private internal 修饰
  • GIS开发入坑(二)--ArcGIS影像切片并使用GeoServer发布

    目录 1 使用ArcGIS切片 1 1修改ArcMap选项 1 2创建切片缓存方案 1 3开始切片 2 使用GeoServer发布切片缓存 2 1 启用GeoWebcache 2 2 发布切片 GeoServer用了一段时间已经略懂一二 实
  • 公网远程连接Oracle数据库【内网穿透】

    文章目录 前言 1 数据库搭建 2 内网穿透 2 1 安装cpolar内网穿透 2 2 创建隧道映射 3 公网远程访问 4 配置固定TCP端口地址 4 1 保留一个固定的公网TCP端口地址 4 2 配置固定公网TCP端口地址 4 3 测试使
  • 浅谈数据模糊搜索

    第一步 既然是搜索那就肯定有一个input输入框 我们使用数据双向绑定绑定input输入框的数据 上代码
  • Linux添加虚拟网卡的多种方法

    Linux添加虚拟网卡的多种方法 有时候 一台服务器需要设置多个ip 但又不想添加多块网卡 那就需要设置虚拟网卡 这里介绍几种方式在linux服务器上添加虚拟网卡 我们向eth0中添加一块虚拟网卡 第一种方法 快递创建 删除虚拟网卡 sud
  • Asp.Net中获取Castle容器中的服务的另一方法

    由于之前的表空间定义得太小 很快就用满了 给表空间新增了一个文件 新增到了4G 但发现还是不行 经查资料 明白除了要扩大表空间之外 还要授权给用户在这个表空间具有不受限制的表空间大小 如下为操作脚本 1 alter tablespace D
  • 赞叹AI的力量-TopazLabs 全家桶使用经历

    一 Topaz Gigapixel AI 之前有用过日本的一个2x提升的在线网站服务waifu2x 是通过深度卷积神经网络来实现的 对于anime style的图片效果是非常好的 使用过之后发现对于一些真实图片效果也不错 只是放大之后能明显
  • 网络营销三大战术品牌应如何选择?

    社会发展的今天 互联网几乎被用于一切事物 交流 学习 娱乐 购物等 目前全球有43 3亿互联网用户 这还是粗略计算并且这个数字每秒钟都在增加 对于营销人员而言这是一个难能可贵的机会 可以如此轻松地接触到如此多的人 在这篇文章中 178软文网
  • Linux高性能服务器编程|阅读笔记:第7章 - Linux服务器程序规范

    目录 简介 系列笔记 7 1 日志 7 1 1 Linux系统日志 7 1 2 syslog函数 7 2 用户信息 7 2 1 UID EUID GID和EGID 7 2 2 切换用户 7 3 进程间关系 7 3 1 进程组 7 3 2 会
  • 2023最新安装微信小程序开发软件安装教程

    一 安装开发者工具 我们在开发小程序之前 首先需要安装小程序开发者工具 今天就来教大家安装小程序开发者工具 微信开放文档 qq com https developers weixin qq com miniprogram dev frame
  • python中 for in 用法_python中for in的用法详解

    for in 说明 也是循环结构的一种 经常用于遍历字符串 列表 元组 字典等 格式 for x in y 循环体 执行流程 x依次表示y中的一个元素 遍历完所有元素循环结束 例1 遍历字符串 s I love you more than
  • Sqlite3 C++ 使用方法

    需要在 C 程序中读写 sqlite3 数据库 查阅了一下资料 发现了一个简单实用教程 另外还有如何在windows下生成sqlite3静态库 生成好的sqlite3静态库可以在这里下载 windows下生成sqlite3静态库 去 sql