标准c语言实现cgi通讯录
时间: 2023-07-13 17:07:21 浏览: 226
c语言实现的通讯录
CGI通讯录是一个常见的Web应用程序,它允许用户添加、编辑、删除和查看联系人信息。在标准C语言中实现CGI通讯录需要以下步骤:
1. 编写HTML页面:首先需要编写一个HTML页面,包含表单和按钮等元素,用于用户输入和提交联系人信息。
2. 编写CGI程序:使用标准C语言编写一个CGI程序,该程序接收来自HTML页面的请求,并处理用户提交的联系人信息。
3. 连接数据库:使用标准C语言提供的数据库API,连接到数据库并执行查询、插入、更新和删除操作。
4. 处理请求:根据用户提交的请求类型(例如添加、编辑、删除或查看联系人),执行相应的操作,并返回结果页面。
下面是一个简单的示例,演示如何使用标准C语言实现CGI通讯录:
HTML页面:
```
<!DOCTYPE html>
<html>
<head>
<title>CGI通讯录示例</title>
</head>
<body>
<h1>CGI通讯录示例</h1>
<form method="post" action="/cgi-bin/addressbook.cgi">
<input type="hidden" name="action" value="add">
<label for="name">姓名:</label>
<input type="text" id="name" name="name"><br>
<label for="phone">电话:</label>
<input type="text" id="phone" name="phone"><br>
<button type="submit">添加</button>
</form>
<hr>
<table>
<tr>
<th>姓名</th>
<th>电话</th>
<th>操作</th>
</tr>
{% for contact in contacts %}
<tr>
<td>{{ contact.name }}</td>
<td>{{ contact.phone }}</td>
<td>
<form method="post" action="/cgi-bin/addressbook.cgi">
<input type="hidden" name="action" value="edit">
<input type="hidden" name="id" value="{{ contact.id }}">
<button type="submit">编辑</button>
</form>
<form method="post" action="/cgi-bin/addressbook.cgi">
<input type="hidden" name="action" value="delete">
<input type="hidden" name="id" value="{{ contact.id }}">
<button type="submit">删除</button>
</form>
</td>
</tr>
{% endfor %}
</table>
</body>
</html>
```
CGI程序:
```
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sqlite3.h>
#define DATABASE "addressbook.db"
typedef struct {
int id;
char name[100];
char phone[100];
} Contact;
void print_header() {
printf("Content-Type: text/html\n\n");
}
void print_error(const char* message) {
print_header();
printf("<p>Error: %s</p>", message);
}
void print_success(const char* message) {
print_header();
printf("<p>%s</p>", message);
}
void print_contacts(Contact* contacts, int count) {
print_header();
printf("<html><head><title>CGI通讯录示例</title></head><body>");
printf("<h1>CGI通讯录示例</h1>");
printf("<form method=\"post\" action=\"/cgi-bin/addressbook.cgi\">");
printf("<input type=\"hidden\" name=\"action\" value=\"add\">");
printf("<label for=\"name\">姓名:</label>");
printf("<input type=\"text\" id=\"name\" name=\"name\"><br>");
printf("<label for=\"phone\">电话:</label>");
printf("<input type=\"text\" id=\"phone\" name=\"phone\"><br>");
printf("<button type=\"submit\">添加</button>");
printf("</form>");
printf("<hr>");
printf("<table>");
printf("<tr><th>姓名</th><th>电话</th><th>操作</th></tr>");
for (int i = 0; i < count; i++) {
printf("<tr>");
printf("<td>%s</td>", contacts[i].name);
printf("<td>%s</td>", contacts[i].phone);
printf("<td>");
printf("<form method=\"post\" action=\"/cgi-bin/addressbook.cgi\">");
printf("<input type=\"hidden\" name=\"action\" value=\"edit\">");
printf("<input type=\"hidden\" name=\"id\" value=\"%d\">", contacts[i].id);
printf("<button type=\"submit\">编辑</button>");
printf("</form>");
printf("<form method=\"post\" action=\"/cgi-bin/addressbook.cgi\">");
printf("<input type=\"hidden\" name=\"action\" value=\"delete\">");
printf("<input type=\"hidden\" name=\"id\" value=\"%d\">", contacts[i].id);
printf("<button type=\"submit\">删除</button>");
printf("</form>");
printf("</td>");
printf("</tr>");
}
printf("</table>");
printf("</body></html>");
}
void add_contact(sqlite3* db, const char* name, const char* phone) {
char* error;
char sql[100];
sprintf(sql, "INSERT INTO contacts (name, phone) VALUES ('%s', '%s')", name, phone);
if (sqlite3_exec(db, sql, NULL, NULL, &error) != SQLITE_OK) {
print_error(error);
} else {
print_success("联系人添加成功!");
}
}
void edit_contact(sqlite3* db, int id, const char* name, const char* phone) {
char* error;
char sql[100];
sprintf(sql, "UPDATE contacts SET name='%s', phone='%s' WHERE id=%d", name, phone, id);
if (sqlite3_exec(db, sql, NULL, NULL, &error) != SQLITE_OK) {
print_error(error);
} else {
print_success("联系人更新成功!");
}
}
void delete_contact(sqlite3* db, int id) {
char* error;
char sql[100];
sprintf(sql, "DELETE FROM contacts WHERE id=%d", id);
if (sqlite3_exec(db, sql, NULL, NULL, &error) != SQLITE_OK) {
print_error(error);
} else {
print_success("联系人删除成功!");
}
}
int get_contacts(sqlite3* db, Contact** contacts) {
sqlite3_stmt* stmt;
const char* tail;
int count = 0;
if (sqlite3_prepare_v2(db, "SELECT id, name, phone FROM contacts", -1, &stmt, &tail) == SQLITE_OK) {
count = sqlite3_column_count(stmt);
*contacts = malloc(sizeof(Contact) * count);
for (int i = 0; i < count; i++) {
(*contacts)[i].id = sqlite3_column_int(stmt, 0);
strcpy((*contacts)[i].name, sqlite3_column_text(stmt, 1));
strcpy((*contacts)[i].phone, sqlite3_column_text(stmt, 2));
}
sqlite3_finalize(stmt);
}
return count;
}
int main() {
sqlite3* db;
if (sqlite3_open(DATABASE, &db) != SQLITE_OK) {
print_error("无法连接到数据库!");
return 1;
}
char* query;
char* method = getenv("REQUEST_METHOD");
if (!strcmp(method, "POST")) {
int content_length = atoi(getenv("CONTENT_LENGTH"));
query = malloc(content_length + 1);
fgets(query, content_length + 1, stdin);
} else {
query = getenv("QUERY_STRING");
}
char* action = strtok(query, "&=");
if (!strcmp(action, "action")) {
char* value = strtok(NULL, "&=");
if (!strcmp(value, "add")) {
char* name = strtok(NULL, "&=");
char* phone = strtok(NULL, "&=");
add_contact(db, name, phone);
} else if (!strcmp(value, "edit")) {
char* id_str = strtok(NULL, "&=");
char* name = strtok(NULL, "&=");
char* phone = strtok(NULL, "&=");
int id = atoi(id_str);
edit_contact(db, id, name, phone);
} else if (!strcmp(value, "delete")) {
char* id_str = strtok(NULL, "&=");
int id = atoi(id_str);
delete_contact(db, id);
}
}
Contact* contacts;
int count = get_contacts(db, &contacts);
print_contacts(contacts, count);
sqlite3_close(db);
return 0;
}
```
说明:
1. 该程序使用SQLite数据库,需要在编译时链接SQLite库,例如:
```
gcc -o addressbook.cgi addressbook.c -lsqlite3
```
2. 该程序使用了模板引擎,使用了类似于Django中的模板语法,可以在程序中自定义模板,这里只是简单地演示一下。
3. 该程序中的SQL语句没有进行参数化处理,存在SQL注入的风险,实际应用中应该使用参数化查询。
4. 该程序中的错误处理比较简单,只是将错误信息输出到页面上,实际应用中应该考虑更完善的错误处理方式。
阅读全文