标准c语言实现通讯录(CGI)

自学,手打,希望多多点赞评论支持,让更多需要的人看见!——花前月

一、配置CGI运行环境——Apache下载安装

下载

阿帕奇豪斯下载 (apachehaus.com)

请添加图片描述

解压缩

在这里插入图片描述

修改配置

修改conf/httpd.conf

在这里插入图片描述

修改Apache存放路径为解压路径

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VBM88YgN-1654222086601)(image/image_FgPvtFEhdn.png)]

修改监听窗口为8086

修改Server Name为127.0.0.1

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XDaN7o2W-1654222086602)(image/image_j1lR98tbdZ.png)]

修改conf/extra/httpd-ahssl.conf和httpd-ssl.conf

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bN15fwS6-1654222086602)(image/image_ssPGE26qu5.png)]

将两个文件的443端口改为444(只要端口不被占用就行)

在这里插入图片描述

测试配置文件是否合法

httpd -t #测试配置文件是否合法

添加环境变量

启动Apache服务

1、使用管理员身份打开cmd(win+R,输入cmd,按ctrl+shift+enter打开),安装Apache服务

httpd -k install -n Apache2.4 #-n后面表示自定义访问名称

在这里插入图片描述

2、启动Apache服务

http -k start

3、查看服务是否启动成功

也可通过此处打开关闭Apache服务

4、测试——在浏览器访问http://127.0.0.1:8086,出现以下页面表示配置成功。

之后我们可以通过修改Apache24\htdocs目录下的index.html文件来更改这个初始页面。

5、停止服务

httpd -k stop   #停止

在这里插入图片描述

二、测试CGI功能

用VS2022新建一个控制台应用程序工程,在主函数中写入:

cout << "Content-type:text/html\n\n";//告诉浏览器将以html的语法来解析此文件
cout << "Hello world";

在这里插入图片描述

先别急着编译,我们先在工程上点右键,选择属性:

在这里插入图片描述

在配置设置-常规中,更改输出目录为cgi-bin下

在这里插入图片描述

在配置属性-高级中更改目标文件的扩展名成cgi

在这里插入图片描述

编译后,我们来到cgi-bin中,就可以看到我们编译生成好的"test.cgi"文件。

在这里插入图片描述

启动Apache服务后,在浏览器中输入localhost/cgi-bin/test.cgi就可以看到hello world了

在这里插入图片描述

只要通过printf或cout,就可以将任何html代码输出在浏览器里。而且,因为是用C/C++写的程序,所以C/C++下的一切函数,都可以用在CGI程序里。

三、向Apache中添加通信录网页

在这里插入图片描述

打开Apache\htdocs,将通讯录网页放置到文件夹中,启动Apache服务后向浏览器中输入127.0.0.1:8086。

在这里插入图片描述

通讯录网页详细代码:

<html>
<head>
<meta charset="gb2312">
<!--规定 HTML 文档的字符编码-->
</head>

<body>
    <form  id ="form" name="form" method="get" action="http://127.0.0.1:8086/cgi-bin/test.cgi" >
    <!--表单数据作为 URL 变量(使用 method="get")发送-->
    <!--action 属性定义提交表单时要执行的操作——跳转到http://127.0.0.1:8086/cgi-bin/test.cgi-->
        
        <P>姓名
            <input type="text" id="name" name="name"/>
            <!--文本框-->
        </P>
  • 21
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
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. 该程序中的错误处理比较简单,只是将错误信息输出到页面上,实际应用中应该考虑更完善的错误处理方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值