news 2026/3/1 3:22:00

简易在线商城制作

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
简易在线商城制作

1.背景描述

在网络购物日益普及的场景下,用户需要一个轻量、高效的在线商城系统,实现商品浏览、搜

索、登录验证等核心功能。当前部分简易商城系统存在功能冗余、运行依赖复杂等问题,而本系统

基于 C 语言开发,无需复杂运行环境,可快速部署在 Linux 平台。

该系统将整合 Web 服务器、SQLite 数据库查询、静态页面展示等功能,支持用户登录验证、商

品搜索、商品详情查看等核心操作,让用户通过浏览器即可完成基础购物相关查询操作,满足简易

场景下的商城使用需求。

2.主要功能实现

(1)登录商城(没有账号可以进行注册)

(2)登陆后进入商品页,可以搜索商品

(3)点击商品查看商品详情。

3.结构框图

4.代码实现

(1)设计登录界面,注册界面,搜索界面以及商品详情页四个html文件

可根据

<style> body{ background-image: url(5.jpg); } </style>

为不同界面添加背景图。

登陆界面
<body> <div class="login-box"> <h2 align=center>用户登录</h2> <form action="http://127.0.0.1:80/login" method="GET"> <div class="form-item"> <h3 align=center><label for="username">用户名</label> <input type="text" id="username" name="username" placeholder="请输入用户名" required></h3> </div> <div class="form-item"> <h3 align=center><label for="password">密&nbsp&nbsp&nbsp&nbsp码</label> <input type="password" id="password" name="password" placeholder="请输入密码" required></h3> </div> <h3 align=center><button type="submit" class="login-btn">登录</button></h3> </form> <div class="register-link"> <h3 align=center>还没有账号?<a href="http://127.0.0.1:80/register.html">立即注册</a></h3> </div> </div> </body>
注册界面
<body> <div class="register-box"> <h2 align="center">用户注册</h2> <form action="http://127.0.0.1:80/register_submit" method="GET"> <div class="form-item"> <h3 align="center"><label for="username">用&nbsp&nbsp户&nbsp&nbsp名</label> <input type="text" id="username" name="username" placeholder="请输入用户名" required></h3> </div> <div class="form-item"> <h3 align="center"><label for="password">密&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp码</label> <input type="password" id="password" name="password" placeholder="请输入密码" required></h3> </div> <div class="form-item"> <h3 align="center"><label for="password2">确认密码</label> <input type="password" id="password2" name="password2" placeholder="请再次输入密码" required></h3> </div> <h3 align="center"><button type="submit" class="register-btn">注册</button></h3> </form> </div> </body>
搜索界面
<body> <div class="nav"> <a href="http://127.0.0.1:80/01.html">返回商品首页</a> | <a href="http://127.0.0.1:80/">退出登录</a> </div> <div class="search-box"> <input type="text" placeholder="请输入商品名称搜索..."> <button>搜索</button> </div> <h2 class="result-title">暂无搜索结果,请返回商品首页浏览</h2> </body>
商品详情页
<body> <div class="nav"> <a href="http://127.0.0.1:80/">退出登录</a> </div> <!-- 搜索框区域 --> <div class="search-container"> <input type="text" id="search-input" placeholder="请输入商品名称"> <button onclick="searchGoods()">搜索</button> </div> <!-- 无结果提示 --> <div class="no-result" id="no-result">暂无商品</div> <!-- 商品列表区域 --> <div class="goods-list" id="goods-list"> <div class="goods-item show">#include <fcntl.h> #include <netinet/in.h> #include <netinet/ip.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <sys/types.h> #include <unistd.h> typedef struct sockaddr*(SA); // 文件类型枚举 typedef enum { FILE_HTML, FILE_PNG, FILE_JPG } FILE_TYPE; // 模拟用户存储 typedef struct { char username[32]; char password[32]; } User; User users[100]; int user_count = 0; // 检查用户 int check_user(const char* name, const char* pass) { for (int i = 0; i < user_count; i++) { if (strcmp(users[i].username, name) == 0 && strcmp(users[i].password, pass) == 0) { return i; } } return -1; } // 注册用户 int register_user(const char* name, const char* pass) { for (int i = 0; i < user_count; i++) { if (strcmp(users[i].username, name) == 0) { return -1; } } if (user_count < 100) { strncpy(users[user_count].username, name, 31); strncpy(users[user_count].password, pass, 31); user_count++; return 0; } return -2; } // 发送文件 int send_file(int conn, char* filename, FILE_TYPE type) { char content_type[64]; if (type == FILE_HTML) strcpy(content_type, "text/html;charset=utf-8"); else if (type == FILE_PNG) strcpy(content_type, "image/png"); else if (type == FILE_JPG) strcpy(content_type, "image/jpeg"); int fd = open(filename, O_RDONLY); if (fd == -1) { char resp[512]; sprintf(resp, "HTTP/1.1 404 Not Found\r\nContent-Type: text/html\r\nConnection: close\r\nContent-Length: %ld\r\n\r\n<h1>文件不存在</h1>", strlen("<h1>文件不存在</h1>")); send(conn, resp, strlen(resp), 0); return 1; } // 获取文件大小 long size = lseek(fd, 0, SEEK_END); lseek(fd, 0, SEEK_SET); // 发送响应头 char header[512]; sprintf(header, "HTTP/1.1 200 OK\r\nContent-Type: %s\r\nContent-Length: %ld\r\nConnection: close\r\n\r\n", content_type, size); send(conn, header, strlen(header), 0); // 发送文件内容 char buf[4096]; ssize_t n; while ((n = read(fd, buf, sizeof(buf))) > 0) { send(conn, buf, n, 0); } close(fd); return 0; } // 发送文本响应 void send_text(int conn, const char* status, const char* content) { char resp[2048]; sprintf(resp, "HTTP/1.1 %s\r\nContent-Type: text/html;charset=utf-8\r\nConnection: close\r\nContent-Length: %ld\r\n\r\n%s", status, strlen(content), content); send(conn, resp, strlen(resp), 0); } void send_goods_page(int conn, int goods_id) { // 商品数据 const char* names[4] = {"苹果", "小米", "oppo", "三星"}; float prices[4] = {4399.00, 2999.00, 3299.00, 2599.00}; int stocks[4] = {1000, 800, 500, 1200}; const char* colors[4] = {"白色/黑色/灰色", "蓝色/黑色/浅蓝", "白色/黑色/米色", "黑色/白色/灰色"}; // 确保ID有效 if (goods_id < 1 || goods_id > 4) goods_id = 1; int idx = goods_id - 1; // 硬编码商品详情页HTML char html[8192]; sprintf(html, "<!DOCTYPE html>" "<html lang='zh-CN'>" "<head>" "<meta charset='UTF-8'>" "<title>%s - 商品商城</title>" "<style>" "* {margin:0;padding:0;box-sizing:border-box;}" "body {font-family:'Microsoft YaHei';margin:50px;background:#f9f9f9;}" ".nav {margin-bottom:30px;padding-bottom:10px;border-bottom:1px solid #eee;}" "a {color:#0088ff;text-decoration:none;margin-right:10px;}" "a:hover {text-decoration:underline;}" ".goods-detail {display:flex;gap:30px;padding:20px;background:white;border-radius:8px;box-shadow:0 2px 8px rgba(0,0,0,0.08);}" ".goods-img img {width:300px;height:220px;object-fit:cover;border:1px solid #eee;border-radius:4px;}" ".thumb-img {margin-top:10px;}" ".thumb-img img {width:80px;height:60px;margin-right:5px;object-fit:cover;cursor:pointer;border:1px solid #eee;border-radius:4px;}" ".goods-info h2 {margin-bottom:15px;color:#e64340;font-size:20px;}" ".goods-info p {margin:10px 0;font-size:16px;color:#555;}" ".goods-info .price {font-size:22px;color:#e64340;font-weight:bold;}" ".goods-info button {padding:10px 25px;background:#e64340;color:white;border:none;border-radius:4px;cursor:pointer;margin-right:10px;margin-top:15px;}" "</style>" "</head>" "<body>" "<div class='nav'>" "<a href='http://127.0.0.1:80/01.html'>返回商品首页</a> | " "<a href='http://127.0.0.1:80/'>退出登录</a>" "</div>" "<div class='goods-detail'>" "<div class='goods-img'>" "<img src='http://127.0.0.1:80/%d.jpg' alt='商品图片' id='main-img'>" "</div>" "<div class='goods-info'>" "<h2>%s</h2>" "<p class='price'>价格:¥%.2f</p>" "<p>库存:%d</p>" "<p>颜色:%s</p>" "</div>" "</div>" "<script>" "function changeImg(n){document.getElementById('main-img').src='http://127.0.0.1:80/'+n+'.jpg';}" "</script>" "</body>" "</html>", names[idx], goods_id, names[idx], prices[idx], stocks[idx],colors[idx] ); // 发送响应 char resp[8192]; sprintf(resp, "HTTP/1.1 200 OK\r\nContent-Type: text/html;charset=utf-8\r\nConnection: close\r\nContent-Length: %ld\r\n\r\n%s", strlen(html), html); send(conn, resp, strlen(resp), 0); } int main() { // 初始化测试用户 strcpy(users[0].username, "zhangsan"); strcpy(users[0].password, "123"); user_count = 1; // 创建套接字 int listen_fd = socket(AF_INET, SOCK_STREAM, 0); if (listen_fd == -1) { perror("socket error"); return 1; } // 端口复用 int opt = 1; setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); // 绑定地址 struct sockaddr_in server_addr; memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = INADDR_ANY; server_addr.sin_port = htons(80); if (bind(listen_fd, (SA)&server_addr, sizeof(server_addr)) == -1) { perror("bind error"); close(listen_fd); return 1; } // 监听 if (listen(listen_fd, 10) == -1) { perror("listen error"); close(listen_fd); return 1; } printf("账号:zhangsan / 123\n"); // 主循环 while (1) { struct sockaddr_in client_addr; socklen_t client_len = sizeof(client_addr); int conn_fd = accept(listen_fd, (SA)&client_addr, &client_len); if (conn_fd == -1) { perror("accept error"); continue; } // 读取请求 char buf[2048]; ssize_t n = read(conn_fd, buf, sizeof(buf)-1); if (n <= 0) { close(conn_fd); continue; } buf[n] = '\0'; // 解析请求路径 char* method = strtok(buf, " "); char* path = strtok(NULL, " "); if (!method || !path) { close(conn_fd); continue; } // 路由处理 if (strcmp(method, "GET") == 0) { // 登录页 if (strcmp(path, "/") == 0 || strcmp(path, "/03.html") == 0) { send_file(conn_fd, "./03.html", FILE_HTML); } // 登录请求 else if (strncmp(path, "/login", 6) == 0) { char* name = strstr(path, "username="); char* pass = strstr(path, "password="); if (name && pass) { name += 9; pass += 9; char* end = strchr(name, '&'); if (end) *end = '\0'; end = strchr(pass, '&'); if (end) *end = '\0'; if (check_user(name, pass) != -1) { send_file(conn_fd, "./01.html", FILE_HTML); } else { send_file(conn_fd, "./04.html", FILE_HTML); } } else { send_text(conn_fd, "400 Bad Request", "<h1>参数错误</h1>"); } } // 注册页 else if (strcmp(path, "/register.html") == 0) { send_file(conn_fd, "./register.html", FILE_HTML); } // 注册请求 else if (strncmp(path, "/register_submit", 15) == 0) { char* name = strstr(path, "username="); char* pass = strstr(path, "password="); char* pass2 = strstr(path, "password2="); if (name && pass && pass2) { name += 9; pass += 9; pass2 += 10; char* end = strchr(name, '&'); if (end) *end = '\0'; end = strchr(pass, '&'); if (end) *end = '\0'; end = strchr(pass2, '&'); if (end) *end = '\0'; if (strcmp(pass, pass2) != 0) { send_text(conn_fd, "200 OK", "<h1>注册失败:两次密码不一致</h1><a href='http://127.0.0.1:80/register.html'>重新注册</a>"); } else if (register_user(name, pass) == -1) { send_text(conn_fd, "200 OK", "<h1>注册失败:用户名已存在</h1><a href='http://127.0.0.1:80/register.html'>重新注册</a>"); } else { send_text(conn_fd, "200 OK", "<h1>注册成功!</h1><a href='http://127.0.0.1:80/'>立即登录</a>"); } } else { send_text(conn_fd, "400 Bad Request", "<h1>参数错误</h1>"); } } // 商品首页(包含搜索功能) else if (strcmp(path, "/01.html") == 0) { send_file(conn_fd, "./01.html", FILE_HTML); } // 登录失败页 else if (strcmp(path, "/04.html") == 0) { send_file(conn_fd, "./04.html", FILE_HTML); } // 搜索页(重定向到商品首页) else if (strcmp(path, "/search.html") == 0 || strncmp(path, "/search", 7) == 0) { send_file(conn_fd, "./01.html", FILE_HTML); } // 商品详情页 else if (strncmp(path, "/goods", 6) == 0) { int goods_id = 1; char* id_str = strstr(path, "id="); if (id_str) goods_id = atoi(id_str + 3); send_goods_page(conn_fd, goods_id); } // 图片资源 else if (strstr(path, ".jpg") || strstr(path, ".png")) { char file_path[256]; sprintf(file_path, ".%s", path); send_file(conn_fd, file_path, strstr(path, ".png") ? FILE_PNG : FILE_JPG); } // 404 else { send_text(conn_fd, "404 Not Found", "<h1>页面不存在</h1><a href='http://127.0.0.1:80/'>返回首页</a>"); } } close(conn_fd); } close(listen_fd); return 0; }

5.结果展示

在线商城

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/18 2:53:10

PO、VO、BO、DTO、DAO、POJO有什么区别?

PO&#xff08;Persistent Object&#xff09;持久化对象&#xff0c;主要用于和数据库交互&#xff0c;是数据库数据在内存中的镜像。 VO&#xff08;View Object&#xff09;视图对象&#xff0c;和前端展示强相关&#xff0c;按需组装前端需要的字段。 BO&#xff08;Busine…

作者头像 李华
网站建设 2026/2/26 16:52:17

大数据领域Zookeeper的集群配置自动化工具推荐

大数据基石的"自动建筑师"&#xff1a;Zookeeper集群配置自动化工具深度解析 关键词 Zookeeper集群、配置自动化、Ansible、Kubernetes Operator、云原生运维、分布式协调、故障容错 摘要 在大数据生态中&#xff0c;Zookeeper作为分布式系统的"协调大脑"&…

作者头像 李华
网站建设 2026/2/19 2:44:31

ArcGIS土地利用现状图制作全流程

将之前《ArcGIS Pro从0到1制作广东省土地利用现状图》直播回重新录制一遍给大家学习。详见下方视频教学 主要涉及的内容包括&#xff1a;ArcGIS土地利用现状图全流程教学&#xff08;从零数据下载、镶嵌、裁剪、属性表连接整理、面积区域汇总计算、地图全流程制作&#xff09; …

作者头像 李华
网站建设 2026/2/28 4:13:53

题解:AT_iroha2019_day3_f 闇のカードゲーム

AT_iroha2019_day3_f 闇のカードゲーム 题目描述 桌上整齐地摆放着 NNN 张卡片&#xff08;NNN 为奇数&#xff09;&#xff0c;每张卡片上有一个正整数。卡片按整数从小到大排列&#xff0c;位于第 iii 张卡片上的整数为 aia_iai​。不同的卡片上不会有相同的整数。 すぬけ君和…

作者头像 李华