Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Clings

Clings 是由 Lingrui Studio 维护的 Rustlings 风格 C 语言练习工具。它读取题库仓库中的 C 源码和 TOML 测试用例,在文件保存后自动编译、运行并反馈结果。

本仓库只包含通用 CLI,不内置课程、题目或参考答案。课程团队可以独立维护题库仓库,并通过 GitHub Classroom 将题目分发给学生。

特性

  • Python 3.11+ 标准库实现,无运行时第三方依赖
  • 支持 GCC、Clang 和常见 MinGW 环境
  • Watch 模式保存即检查,并记录本地学习进度
  • 支持退出码、标准输出、仅编译、Makefile 等评测方式
  • 题目、提示和公开测试全部由题库仓库管理
  • 支持教师使用独立参考答案目录验证题库

安装

需要 Python 3.11+ 和 C 编译器。GNU Make 只在题目使用 Makefile 时需要;题库的 setup.sh 可以一键安装。

#!/bin/sh
set -eu

command -v uv >/dev/null 2>&1 || {
    echo "未找到 uv,正在安装。.."
    UV_INSTALL_DIR="${UV_INSTALL_DIR:-$HOME/.local/bin}"
    export UV_INSTALL_DIR

    if command -v curl >/dev/null 2>&1; then
        curl -LsSf https://astral.sh/uv/install.sh | sh
    elif command -v wget >/dev/null 2>&1; then
        wget -qO- https://astral.sh/uv/install.sh | sh
    else
        echo "安装 uv 需要 curl 或 wget" >&2
        exit 1
    fi

    PATH="$UV_INSTALL_DIR:$PATH"
    export PATH
}

command -v uv >/dev/null 2>&1 || {
    echo "uv 安装失败,请检查网络连接后重试" >&2
    exit 1
}

uv tool install --force \
    "git+https://github.com/Lingrui-Studio/clings.git"

clings doctor

使用

在包含 clings.tomlexercises/ 的题库根目录运行:

clings                  # 进入交互式 Watch 模式
clings list             # 查看题目与进度
clings hint             # 查看下一道未完成题目的提示
clings tests 01_hello   # 查看公开测试用例
clings run 01_hello     # 运行指定题目
clings check            # 依次检查全部题目,遇到失败即停止
clings score --json     # 检查全部题目并生成 JSON 报告
clings reset 01_hello   # 用 Git 中的版本恢复题目文件
clings reset progress   # 清除本地进度

题目可以通过名称、名称前缀、Unit 或 Lesson 编号筛选:

clings watch unit1
clings check unit1
clings run 2
clings hint pointer

进度保存在 .clings-state.txt,编译产物保存在 .clings/build/。这两个路径应加入题库仓库的 .gitignore

题库结构

一个最小题库仓库如下:

c-exercises/
├── README.md
├── setup.sh
├── clings.toml
├── tests/                         # 可选:独立公开测试
│   └── 01_hello.toml
└── exercises/
    ├── 01_hello/
    │   ├── README.md              # 题目说明
    │   ├── exercises.toml         # 元数据、提示和内联测试
    │   └── hello.c                # 学生编辑的代码
    └── 02_sum/
        ├── README.md
        ├── exercises.toml
        └── sum.c

根目录必须存在 clings.toml。Unit 信息可集中写在这里:

[[units]]
id = "unit1"
title = "C 语言基础"
lessons = "01-10"

Clings 会自动扫描 exercises/**/exercises.toml,无需在根配置中重复登记每道题。

编写题目

推荐每个 Lesson 使用一个目录。一个目录可以包含一道或多道练习:

[[exercises]]
name = "01_hello"
title = "输出 Hello, World!"
unit = "unit1"
lesson = 1
order = 1
mode = "stdout"
source = "hello.c"
hint = "使用 printf,并注意末尾换行。"

[[exercises.cases]]
stdin = ""
stdout = """
Hello, World!
"""

学生源码可以使用 #error TODO 标记尚未完成的位置:

#include <stdio.h>

int main(void) {
    #error TODO
    return 0;
}

评测模式

模式 配置 行为
return expected_return = 0 编译并检查程序退出码
stdout [[exercises.cases]] 编译后逐个运行测试用例
compile 无额外配置 只要求编译成功
make make_targets = ["test"] 运行一个或多个 Make target
make+stdout binarymake_targets、测试用例 使用 Makefile 构建后检查程序输出

stdoutmake+stdout 用例支持以下字段:

[[exercises.cases]]
stdin = "3 4\n"
args = ["--verbose"]
exit_code = 0
stdout = "7\n"
timeout = 2.0
trim_trailing_ws = true

还可以使用 stdout_containsstdout_not_containsstdout_regexstdout_b64 描述不适合精确字符串比较的输出。

测试用例默认直接写在 exercises.toml 中。较长的用例可以放在题库根目录的 tests/<exercise-name>.toml

[[cases]]
stdin = "3 4\n"
stdout = "7\n"

如果外部测试文件存在,它会覆盖该题的内联用例。所有这些测试都是题库的一部分,学生可以查看。

验证参考答案

教师可以在另一个目录维护参考答案,目录结构与题库中的 exercises/ 一致:

solutions/
├── 01_hello/hello.c
└── 02_sum/sum.c

通过环境变量指定该目录:

CLINGS_SOLUTIONS_DIR=/path/to/solutions clings check --solutions

参考答案不应提交到面向学生的题库仓库。

开发

git clone https://github.com/Lingrui-Studio/clings.git
cd clings
uv sync --extra dev
uv run pytest
uv run python -m clings --version

CLI 的运行时功能只使用 Python 标准库。pytestpytest-cov 仅用于本仓库开发测试。

License

本项目采用 MIT License

上游项目

本项目基于 OpenCamp C Camp Team 的 clings 修改:

https://cnb.cool/opencamp/learning-nccl/clings

原项目与本项目均采用 MIT License。感谢原作者和贡献者的开源工作。

About

Clings. C 语言版 Rustlings — 通过修复编译错误、补全代码来学习 C 语言。

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages