首页 > 后端开发 > C++ > 正文

C++制作简单购物车程序实例

P粉602998670
发布: 2025-09-05 11:14:02
原创
897人浏览过
C++购物车程序通过结构体Product和CartItem管理商品及购物车数据,使用std::vector存储商品列表和购物车内容,结合菜单循环实现用户交互;程序定义displayProducts、addToCart、viewCart和checkout等函数完成核心功能,通过输入验证和clearInputBuffer处理用户输入错误,在添加商品时检查ID有效性、数量正负及库存充足性,购物车显示与结账时遍历商品计算总价并格式化输出金额,所有操作均在主循环中通过switch分支调用对应函数实现,确保逻辑清晰且具备基础异常处理能力。

c++制作简单购物车程序实例

用C++构建一个简单的购物车程序,核心在于有效地管理商品数据、购物车状态,并提供直观的用户交互界面。这通常涉及结构体或类来定义商品,以及STL容器(如

std::vector
登录后复制
std::map
登录后复制
)来存储商品列表和购物车中的物品。通过一个循环菜单,用户可以浏览商品、添加商品到购物车、查看购物车内容并最终结账。

解决方案

制作一个简单的C++购物车程序,我们可以从定义商品结构开始,然后构建几个核心功能函数:展示商品、添加商品到购物车、查看购物车以及计算总价。

首先,我们需要一个结构体来表示商品:

#include <iostream>
#include <vector>
#include <string>
#include <iomanip> // For std::fixed and std::setprecision
#include <limits>  // For std::numeric_limits

// 商品结构体
struct Product {
    int id;
    std::string name;
    double price;
    int stock; // 简单库存管理
};

// 购物车中的商品项
struct CartItem {
    int productId;
    int quantity;
    // 实际项目中可能还会存储商品名称和价格,避免多次查找
};

// 全局商品列表 (实际项目中可能从文件或数据库加载)
std::vector<Product> products = {
    {1, "笔记本电脑", 5999.00, 10},
    {2, "无线鼠标", 129.50, 50},
    {3, "机械键盘", 349.00, 20},
    {4, "显示器", 1299.00, 15},
    {5, "USB集线器", 88.00, 100}
};

// 购物车 (存储商品ID和数量)
std::vector<CartItem> cart;

// 函数声明
void displayProducts();
void addToCart();
void viewCart();
void checkout();
void clearInputBuffer(); // 辅助函数,处理cin失败后的输入流

int main() {
    int choice;
    do {
        std::cout << "\n--- 简易购物车程序 ---\n";
        std::cout << "1. 浏览商品\n";
        std::cout << "2. 添加商品到购物车\n";
        std::cout << "3. 查看购物车\n";
        std::cout << "4. 结账\n";
        std::cout << "5. 退出\n";
        std::cout << "请输入您的选择: ";

        if (!(std::cin >> choice)) {
            std::cout << "无效输入,请输入数字。\n";
            clearInputBuffer();
            continue;
        }

        switch (choice) {
            case 1: displayProducts(); break;
            case 2: addToCart(); break;
            case 3: viewCart(); break;
            case 4: checkout(); break;
            case 5: std::cout << "感谢使用,再见!\n"; break;
            default: std::cout << "无效选择,请重新输入。\n"; break;
        }
    } while (choice != 5);

    return 0;
}

// 清理输入缓冲区
void clearInputBuffer() {
    std::cin.clear();
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}

// 1. 显示所有商品
void displayProducts() {
    std::cout << "\n--- 商品列表 ---\n";
    std::cout << "ID\t名称\t\t价格\t库存\n";
    std::cout << "-------------------------------------------\n";
    for (const auto& p : products) {
        std::cout << p.id << "\t" << std::left << std::setw(15) << p.name
                  << "\t" << std::fixed << std::setprecision(2) << p.price
                  << "\t" << p.stock << "\n";
    }
    std::cout << "-------------------------------------------\n";
}

// 2. 添加商品到购物车
void addToCart() {
    int productId, quantity;
    std::cout << "\n--- 添加商品到购物车 ---\n";
    std::cout << "请输入商品ID: ";
    if (!(std::cin >> productId)) {
        std::cout << "无效输入,请输入数字ID。\n";
        clearInputBuffer();
        return;
    }

    // 查找商品
    Product* foundProduct = nullptr;
    for (auto& p : products) {
        if (p.id == productId) {
            foundProduct = &p;
            break;
        }
    }

    if (!foundProduct) {
        std::cout << "商品ID不存在。\n";
        return;
    }

    std::cout << "请输入购买数量: ";
    if (!(std::cin >> quantity)) {
        std::cout << "无效输入,请输入数字数量。\n";
        clearInputBuffer();
        return;
    }

    if (quantity <= 0) {
        std::cout << "购买数量必须大于0。\n";
        return;
    }

    if (quantity > foundProduct->stock) {
        std::cout << "库存不足!当前库存为: " << foundProduct->stock << "\n";
        return;
    }

    // 检查购物车中是否已有该商品
    bool itemExistsInCart = false;
    for (auto& item : cart) {
        if (item.productId == productId) {
            item.quantity += quantity;
            itemExistsInCart = true;
            break;
        }
    }

    if (!itemExistsInCart) {
        cart.push_back({productId, quantity});
    }

    foundProduct->stock -= quantity; // 更新库存
    std::cout << foundProduct->name << " 已成功添加到购物车,数量: " << quantity << "\n";
}

// 3. 查看购物车
void viewCart() {
    std::cout << "\n--- 您的购物车 ---\n";
    if (cart.empty()) {
        std::cout << "购物车是空的。\n";
        return;
    }

    double total = 0.0;
    std::cout << "ID\t名称\t\t数量\t单价\t小计\n";
    std::cout << "---------------------------------------------------\n";
    for (const auto& item : cart) {
        // 再次查找商品信息,这里效率不高,实际中可以优化
        const Product* p = nullptr;
        for (const auto& prod : products) {
            if (prod.id == item.productId) {
                p = &prod;
                break;
            }
        }

        if (p) {
            double subtotal = p->price * item.quantity;
            total += subtotal;
            std::cout << p->id << "\t" << std::left << std::setw(15) << p->name
                      << "\t" << item.quantity << "\t"
                      << std::fixed << std::setprecision(2) << p->price << "\t"
                      << std::fixed << std::setprecision(2) << subtotal << "\n";
        }
    }
    std::cout << "---------------------------------------------------\n";
    std::cout << "总计: \t\t\t\t\t" << std::fixed << std::setprecision(2) << total << "\n";
}

// 4. 结账
void checkout() {
    std::cout << "\n--- 结账 ---\n";
    if (cart.empty()) {
        std::cout << "购物车是空的,无法结账。\n";
        return;
    }

    viewCart(); // 先显示购物车内容
    double total = 0.0;
    for (const auto& item : cart) {
        for (const auto& p : products) {
            if (p.id == item.productId) {
                total += p.price * item.quantity;
                break;
            }
        }
    }

    std::cout << "\n您的订单总金额为: " << std::fixed << std::setprecision(2) << total << " 元。\n";
    std::cout << "感谢您的购买!订单已处理。\n";
    cart.clear(); // 清空购物车
}
登录后复制

C++购物车程序如何管理商品信息?

在C++中管理商品信息,我通常会倾向于使用结构体(

struct
登录后复制
)或者类(
class
登录后复制
)来封装商品的各种属性。对于一个像购物车这样的小程序
struct
登录后复制
通常就足够了,它简洁明了,能很好地把商品的ID、名称、价格和库存这些基本信息捆绑在一起。比如上面代码中的
Product
登录后复制
结构体,它包含了商品的所有关键数据。

立即学习C++免费学习笔记(深入)”;

至于存储这些商品,

std::vector<Product>
登录后复制
是一个非常直接且实用的选择。它就像一个动态数组,可以很方便地添加、遍历和查找商品。当你需要查找某个特定ID的商品时,虽然
std::vector
登录后复制
需要线性遍历,但对于商品数量不多的情况,性能影响几乎可以忽略不计。如果商品数量非常庞大,我们可能会考虑
std::map<int, Product>
登录后复制
,这样可以通过ID直接进行O(log N)或O(1)(如果是
std::unordered_map
登录后复制
)的查找,效率会高很多。不过,对于初学者或者这个“简单”的购物车实例,
std::vector
登录后复制
在实现上会更直观一些,我个人觉得没必要一开始就搞得太复杂。

另外,购物车本身也需要管理商品信息,但它只关心用户选择了哪些商品以及每种商品的数量。所以,一个

CartItem
登录后复制
结构体,包含
productId
登录后复制
quantity
登录后复制
就足够了。购物车本身也可以用
std::vector<CartItem>
登录后复制
来表示。这种方式允许购物车里有多个同类商品(虽然我在示例中处理成了合并数量),也方便后续扩展。

Giiso写作机器人
Giiso写作机器人

Giiso写作机器人,让写作更简单

Giiso写作机器人 56
查看详情 Giiso写作机器人

C++如何处理用户输入与购物车逻辑交互?

处理用户输入,说实话,这是任何交互式程序里最容易出问题的地方。用户可不会乖乖地按照你的预期输入数字。在C++中,我们主要依赖

std::cin
登录后复制
来获取用户输入。但仅仅使用
std::cin >> variable;
登录后复制
是不够的,因为它很容易因为输入类型不匹配(比如用户输入了字母而不是数字)而导致输入流进入错误状态。

我的做法是,每次

std::cin
登录后复制
操作后,都应该检查其状态。如果
std::cin
登录后复制
失败了(
if (!(std::cin >> choice))
登录后复制
),这意味着输入不合法。这时,我们必须做三件事:

  1. std::cin.clear();
    登录后复制
    : 清除
    std::cin
    登录后复制
    的错误标志,让它恢复正常工作。
  2. std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    登录后复制
    : 忽略当前输入行中剩余的所有字符,直到遇到换行符。这能确保下一次读取不会被之前的错误输入干扰。
  3. 给出错误提示并重新引导用户: 告诉用户输入有误,并让他们重新输入。

在购物车逻辑交互方面,一个清晰的菜单是必不可少的。通过一个

do-while
登录后复制
循环来展示主菜单,并使用
switch
登录后复制
语句根据用户的选择调用不同的功能函数,这是最常见也最有效的方式。比如,用户选择“1”就调用
displayProducts()
登录后复制
,选择“2”就调用
addToCart()
登录后复制
。在
addToCart()
登录后复制
这样的功能里,除了检查输入是否为数字,我们还需要进行业务逻辑上的验证,比如商品ID是否存在、购买数量是否大于零、库存是否充足等。这些验证确保了程序的健壮性和数据的正确性。我个人觉得,这些输入验证和业务规则的判断,虽然增加了代码量,但却是构建一个“能用”的程序不可或缺的部分。否则,用户随便输个错,程序就崩了,那体验可太糟糕了。

C++购物车程序如何计算总价并处理异常情况?

计算总价相对直接,一旦购物车中有商品,我们只需要遍历

cart
登录后复制
中的每一个
CartItem
登录后复制
,然后根据
productId
登录后复制
products
登录后复制
列表中找到对应的商品价格,再乘以
CartItem
登录后复制
中的
quantity
登录后复制
,累加起来就是总价了。在
viewCart()
登录后复制
checkout()
登录后复制
函数中,我都实现了这个逻辑。需要注意的是,为了显示更友好的价格,我会用到
iomanip
登录后复制
库中的
std::fixed
登录后复制
std::setprecision(2)
登录后复制
来确保金额总是显示两位小数。

至于异常情况处理,除了前面提到的用户输入错误,还有一些业务逻辑上的“异常”需要考虑:

  • 购物车为空时尝试查看或结账: 这时程序不应该崩溃,而是应该友好地提示用户“购物车是空的”。
  • 添加不存在的商品ID: 需要检查用户输入的
    productId
    登录后复制
    是否真的存在于
    products
    登录后复制
    列表中。
  • 购买数量为零或负数: 数量必须是正整数。
  • 购买数量超过库存: 这是最常见的,必须检查
    quantity
    登录后复制
    是否小于或等于
    stock
    登录后复制
    。如果不足,要给出明确提示,并阻止购买。

我在

addToCart()
登录后复制
函数中就处理了这些情况,比如
if (!foundProduct)
登录后复制
if (quantity <= 0)
登录后复制
if (quantity > foundProduct->stock)
登录后复制
。这些都是为了让程序更“傻瓜式”,即便用户操作失误,程序也能给出合理的反馈,而不是直接报错或者进入奇怪的状态。当然,这只是最基础的异常处理。一个更完善的系统还会考虑多线程并发访问库存、网络请求失败、数据库连接中断等更复杂的“异常”,但对于一个简单的命令行购物车程序,这些已经足够了。

以上就是C++制作简单购物车程序实例的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号