C语言格式化字符串进阶:动态宽度与精度控制实战
1. 从“%d”到“%*d”一个被忽视的格式化“开关”刚接触C语言时我们都是从printf(“Hello, %s!”, name);和scanf(“%d”, age);开始的。%d、%s、%f这些基础占位符就像工具箱里的螺丝刀和扳手简单直接。但当你开始处理更复杂的数据比如需要动态控制输出宽度、从混乱的输入流中精准提取部分数据或者格式化表格时你会发现基础工具不够用了。这时格式化字符串中那些带*号的“高级”占位符如%*d和%.*s就从幕后走到了台前。很多人觉得它们冷门、复杂选择绕道而行用一堆if-else和手动计算来替代。但在我看来这无异于放着自动挡不开非要练跟趾。这些带*的格式符本质上是将格式化的部分控制权从“编译时写死”变成了“运行时动态决定”。理解并掌握它们不仅能让你写出更简洁、更灵活的代码更能让你深刻理解C语言格式化输入输出的设计哲学——一种基于可变参数列表的、高度可定制的数据转换协议。今天我们就抛开教科书上那几行简单的定义深入printf和scanf的“引擎盖”下看看%*d和%.*s这些符号到底如何工作以及在实际项目中它们能帮你解决哪些实实在在的难题。2. 格式化字符串的精髓不只是替换文本在深入*号之前我们必须重新审视一下printf和scanf家族函数的核心——格式化字符串。它绝不仅仅是一个“带占位符的模板”。2.1 格式化字符串的完整结构一个完整的转换说明符conversion specification通常遵循以下格式%[标志][宽度][.精度][长度修饰符]转换说明符各部分含义如下标志- 空格 # 0控制对齐、符号、前缀等。宽度指定最小字段宽度。输出数据若短于此宽度则用空格或0填充。精度以点 . 开头对于数值指定最小输出位数整数或小数点后位数浮点对于字符串指定最大输出字符数。长度修饰符h, l, ll, L等指定参数的大小如%hd表示short int%lld表示long long int。转换说明符d, i, f, s, c, p等指定参数的数据类型和转换方式。关键点在于在标准的格式化字符串中宽度和精度通常被写作固定的数字例如%6d宽度6、%.3f精度3。这种“硬编码”的方式在简单场景下没问题但一旦宽度或精度需要根据程序运行时的变量来决定就束手无策了。而*号就是为解决这个问题而生的动态占位符。2.2*号的角色运行时参数的“占坑者”在宽度或精度的位置上如果你不写一个固定数字而是写一个*那么函数会从参数列表中额外消耗一个整数参数并用这个整数的值作为宽度或精度。核心机制printf和scanf使用可变参数列表va_list来访问传入的额外参数。函数解析格式化字符串从左到右依次处理。当遇到一个转换说明符时它根据说明符的类型如%d从参数列表中取出一个对应类型的值。如果在该说明符的宽度或精度位置发现了*它会先于转换目标值从参数列表中取出一个int类型的值作为动态的宽度或精度。这就好比点餐固定格式%6d像是“一份6寸的披萨”而%*d则是“一份请告诉我尺寸寸的披萨”服务员printf需要你先额外告诉他一个尺寸参数。注意这个用于提供宽度/精度值的int参数必须是有符号整数。虽然宽度和精度在概念上应为非负但C标准允许负值并定义了相应的行为通常负宽度被解释为左对齐标志-加上正宽度。在实际编码中应确保传入合理的非负值以避免未定义行为。3.%*d在printf中的实战打造对齐的表格输出%*d在printf中最经典的用途就是动态控制输出字段的宽度实现整齐的表格化输出尤其是在你不知道数据最大宽度的时候。3.1 基础用法与参数顺序#include stdio.h int main() { int width 8; int number 12345; printf(|%*d|\n, width, number); return 0; }输出| 12345|发生了什么printf遇到%*d它知道需要两个额外参数一个int作为宽度另一个int作为要输出的值。它首先取出width的值8然后取出number的值12345。最后它在一个宽度为8的字段中右对齐打印12345不足部分用空格在左侧填充。3.2 复杂场景动态列宽与对齐假设你要打印一个产品价格表产品ID和价格的长度都可能变化你希望各列能根据内容自动调整到合适的宽度。#include stdio.h void print_product_table(int id_width, int price_width) { // 假设从数据库或文件读取了以下数据 int ids[] {1, 22, 333, 4444}; double prices[] {9.99, 1234.5, 78.0, 5.6}; int count 4; printf(%-*s %-*s\n, id_width, ID, price_width, Price); // 表头左对齐 printf(%*s %*s\n, id_width, , price_width, ); // 分隔线 for (int i 0; i count; i) { // ID右对齐价格保留两位小数并右对齐 printf(%*d %*.*f\n, id_width, ids[i], price_width, 2, prices[i]); } } int main() { // 第一版固定宽窄 printf(Table 1 (Fixed narrow):\n); print_product_table(6, 10); printf(\n); // 第二版根据可能的最大值设置更宽的列 printf(Table 2 (Adjusted wider):\n); print_product_table(8, 12); return 0; }输出示例Table 1 (Fixed narrow): ID Price 1 9.99 22 1234.50 333 78.00 4444 5.60 Table 2 (Adjusted wider): ID Price 1 9.99 22 1234.50 333 78.00 4444 5.60实操心得计算动态宽度在实际项目中id_width和price_width很少是硬编码的。更常见的做法是在读取所有数据后先遍历一遍找出ID和Price字符串形式的最大长度然后在此基础上加1或2作为列宽这样表格总能完美容纳数据。对齐组合注意%-*s中的-标志。它表示左对齐。-标志和动态宽度*可以组合使用顺序是%后紧跟标志如-然后是*。printf(“%-*s”, width, “Hello”);会在一个宽度为width的字段中左对齐打印 “Hello”。精度与宽度的组合%*.*f用第一个*指定总字段宽度第二个*指定小数点后的精度。这在需要统一小数位数且对齐的财务报告中非常有用。3.3 常见陷阱参数顺序错误这是新手最容易栽跟头的地方。printf的参数消耗顺序是严格遵循格式化字符串的解析顺序的。int a 5, b 10, value 42; printf(“%*d\n”, a, b, value); // 错误有歧义。上面这行代码意图模糊。%*d需要两个参数a作为宽度b作为输出值。那么value这个参数就多余了它会被忽略。如果你本意是用a作宽度输出value那就写错了正确的应该是printf(“%*d\n”, a, value);。排查技巧当printf输出结果完全不符合预期或者程序出现奇怪的崩溃访问了错误的栈地址时首先检查格式化字符串与参数列表是否严格匹配。特别是使用了多个*时务必数清需要多少个整数参数以及它们的位置。4.%.*s在printf中的妙用安全截断与子串输出如果说%*d控制的是“舞台”的宽度那么%.*s控制的就是“演员”字符串出场的长度。这是防止缓冲区溢出、进行字符串截断显示的利器。4.1 基础用法精确控制输出字符数#include stdio.h int main() { char long_string[] “This is a very long string that we might not want to print fully.”; int max_len 20; printf(“完整字符串: ‘%s’\n”, long_string); printf(“截断前 %d 字符: ‘%.*s’\n”, max_len, max_len, long_string); // 也可以组合宽度和精度 printf(“在30宽字段中截断20字符右对齐: ‘%30.*s’\n”, max_len, long_string); printf(“在30宽字段中截断20字符左对齐: ‘%-30.*s’\n”, max_len, long_string); return 0; }输出完整字符串: ‘This is a very long string that we might not want to print fully.’ 截断前 20 字符: ‘This is a very long ’ 在30宽字段中截断20字符右对齐: ‘ This is a very long ’ 在30宽字段中截断20字符左对齐: ‘This is a very long ’4.2 实战场景日志系统与安全输出场景一固定长度的日志条目在嵌入式系统或需要整齐日志的场合每条日志信息可能要求固定长度。void log_message(int level, const char *file, int line, const char *msg) { // 假设我们定义日志级别和文件名输出各占固定宽度消息部分最多显示50字符 const char *level_str[] {“DEBUG”, “INFO”, “ERROR”}; int msg_max_len 50; // 动态计算文件名显示长度比如只显示最后15个字符 int file_display_len 15; const char *file_end file; while (*file_end) file_end; // 找到字符串结尾 // 如果文件名长于15指向倒数第15个字符的位置 const char *file_start (file_end - file file_display_len) ? file_end - file_display_len : file; printf(“[%-5s] %.*s:%4d | %.*s\n”, level_str[level], file_display_len, file_start, // 动态精度控制文件名显示长度 line, msg_max_len, msg); // 动态精度控制消息长度 }场景二安全输出不可信数据处理网络数据或用户输入时字符串可能没有终止符\0或者长度未知直接使用%s输出是危险的。// 假设我们从某个缓冲区 buf 读取了 data_len 字节的数据它可能不是合法的C字符串 void safe_print_buffer(const unsigned char *buf, size_t data_len) { // 我们只想打印前 data_len 个字节即使中间有 ‘\0’ printf(“Received data (first %zu bytes): %.*s\n”, data_len, (int)data_len, (const char*)buf); // 注意精度 .* 要求一个 int 参数所以将 size_t 转换。确保 data_len 不超过 INT_MAX。 }重要警告%.*s虽然能防止printf因寻找\0而越界但它要求传入的指针和长度是有效的。如果data_len超出了缓冲区实际分配的大小你仍然在向printf传递错误的长度信息这可能导致读取无效内存。它只是解决了%s的字符串终止问题并没有替代对缓冲区长度的严格检查。4.3 精度为0或负数的行为char str[] “Hello”; printf(“‘%.*s’\n”, 0, str); // 输出: ‘’ (空字符串) printf(“‘%.*s’\n”, -1, str); // 输出: ‘Hello’ (负精度通常被当作未指定精度处理输出整个字符串)了解这些边界情况有助于处理动态计算精度时可能出现的边缘值。5.scanf中的%*d与%*s过滤与跳过输入在scanf家族函数中*号扮演了一个完全不同的角色赋值抑制符assignment suppression character。它的意思是按照后面的格式说明符如d,s,f解析输入流中的对应数据但不将结果存储到任何变量中即“读但扔掉”。5.1 基础用法跳过不需要的数据想象你有一个数据文件每一行格式是日期 时间 数值1 数值2 状态而你只关心数值1和数值2。#include stdio.h int main() { FILE *fp fopen(“data.txt”, “r”); if (!fp) return 1; int value1, value2; char date[11], time[9]; // 假设日期格式 YYYY-MM-DD时间 HH:MM:SS char status; // 使用 %*s 跳过日期和时间或者直接用一个 %*[^ ] 跳过非空格序列 while (fscanf(fp, “%10s %8s %d %d %c”, date, time, value1, value2, status) 5) { // 成功读取了一行但 date, time, status 可能我们不需要 printf(“Value1: %d, Value2: %d\n”, value1, value2); } fclose(fp); // 更简洁的写法直接跳过前两个字段 rewind(fp); // 回到文件开头仅用于演示 printf(“\n— Using suppression —\n”); while (fscanf(fp, “%*s %*s %d %d %*c”, value1, value2) 2) { // 注意状态码也被跳过了 printf(“Value1: %d, Value2: %d\n”, value1, value2); } fclose(fp); return 0; }关键点在scanf的格式字符串“%*s %*s %d %d %*c”中%*s读取一个非空白字符序列直到遇到空白然后丢弃。%d %d正常读取两个整数存储到value1和value2。%*c读取一个字符这里是状态码然后丢弃。返回值fscanf返回成功匹配并赋值的输入项数。因为使用了抑制符*被跳过的项不计入成功赋值项。所以这个scanf调用成功时返回2两个%d而不是5。5.2 高级过滤处理不规则分隔符%*[^]格式在跳过复杂数据时非常强大。%[^,]表示匹配一个不包含逗号的字符串加上*就是匹配并跳过它。// 输入行: “John Doe, 30, New York, Engineer” char name[50]; int age; char city[50]; // 只想读取姓名和年龄跳过城市和职业 scanf(“%49[^,], %d, %*[^,], %*[^\n]”, name, age);解析%49[^,]读取最多49个非逗号字符作为姓名。,匹配输入中的逗号和空格。%d读取年龄。, %*[^,]匹配逗号空格然后读取并跳过一个非逗号字符串城市。, %*[^\n]匹配逗号空格然后读取并跳过后面的所有字符直到行尾职业。5.3 常见问题与避坑指南输入缓冲区残留scanf的跳过操作依然会消耗输入。如果格式字符串设计不当可能导致后续读取错位。建议在复杂的scanf解析后使用while(getchar() ! ‘\n’);清空输入缓冲区尤其是在混合使用%c与其他格式符时。匹配失败导致的问题如果输入数据与格式字符串不匹配例如期望数字却收到了字母scanf会停止解析并且抑制符*之前的成功匹配项可能已被丢弃但输入流指针会停留在失败的位置导致后续所有读取都失败。建议总是检查scanf的返回值确保它等于你期望成功赋值的参数个数不包括抑制符对应的部分。字段宽度与抑制符抑制符*可以和字段宽度一起使用例如%*10s表示跳过最多10个字符的非空白序列。这在读取固定格式的垃圾数据时有用。6. 综合案例一个简单的数据清洗与格式化报告工具让我们把这些知识融合到一个假设的场景中你有一个格式混乱的原始数据文件raw_data.txt内容如下# 这是一个注释行 2024-05-20 14:30:01 1001 192.168.1.1 SUCCESS 450ms 2024-05-20 14:30:02 1002 10.0.0.15 FAILURE timeout 2024-05-20 14:30:05 1003 172.16.254.1 SUCCESS 120ms # 另一个注释 2024-05-20 14:30:10 1004 192.168.1.105 SUCCESS 890ms你需要编写一个程序跳过注释行提取时间戳中的时间部分、请求ID、IP地址的最后一组数字、状态和耗时数值并按照整齐的表格打印报告。#include stdio.h #include stdlib.h // for strtol #include string.h int main() { FILE *fp fopen(“raw_data.txt”, “r”); if (!fp) { perror(“Failed to open file”); return 1; } char line[256]; char date[11], time[9], ip[16], status[10], latency_str[10]; int req_id, ip_last_octet, latency_ms; int max_id_width 4, max_ip_width 3, max_status_width 7, max_latency_width 8; // 初始估计 // 第一遍计算最大宽度简单演示实际可能需要更精确计算 while (fgets(line, sizeof(line), fp)) { if (line[0] ‘#’) continue; // 跳过注释行 // 尝试解析但不存储只为计算宽度 if (sscanf(line, “%10s %8s %d %15s %9s %9s”, date, time, req_id, ip, status, latency_str) 6) { // 解析IP最后一组数字 char *last_dot strrchr(ip, ‘.’); if (last_dot) { int octet atoi(last_dot 1); // 更新最大宽度这里简化实际应用应计算字符串长度 if (req_id 9999) max_id_width 5; if (octet 999) max_ip_width 4; if (strlen(status) max_status_width) max_status_width strlen(status); if (strlen(latency_str) max_latency_width) max_latency_width strlen(latency_str); } } } rewind(fp); // 回到文件开头准备正式处理 // 打印表头 printf(“%-8s %-*s %-*s %-*s %-*s\n”, “Time”, max_id_width, “ReqID”, max_ip_width, “IP(Last)”, max_status_width, “Status”, max_latency_width, “Latency”); printf(“%*s\n”, 8 2 max_id_width 2 max_ip_width 2 max_status_width 2 max_latency_width, “”); // 上面一行打印分隔线宽度动态计算 // 第二遍正式读取、解析和格式化输出 while (fgets(line, sizeof(line), fp)) { if (line[0] ‘#’) continue; // 使用 sscanf 解析注意 latency_str 可能包含 “ms” if (sscanf(line, “%*s %8s %d %15s %9s %9s”, time, req_id, ip, status, latency_str) 5) { // 提取IP最后一个点分十进制 char *last_dot strrchr(ip, ‘.’); ip_last_octet last_dot ? atoi(last_dot 1) : 0; // 从 latency_str 中提取数字部分例如 “450ms” - 450 latency_ms (int)strtol(latency_str, NULL, 10); // 使用动态宽度进行格式化输出 printf(“%-8s %*d %*d %-*s %*dms\n”, time, max_id_width, req_id, max_ip_width, ip_last_octet, max_status_width, status, max_latency_width - 2, latency_ms); // -2 因为加了 “ms” 后缀 } } fclose(fp); return 0; }这个案例综合运用了scanf中的%*s在第二次sscanf中%*s跳过了日期字段因为我们只关心时间。printf中的%*d和%-*s根据第一遍扫描计算出的最大宽度动态控制表格各列的宽度和对齐方式。字符串处理使用strrchr和strtol来解析IP和延迟字符串。通过这个例子你可以看到将静态的格式字符串与动态的*占位符结合能够写出适应性强、输出美观的代码这正是%*d和%.*s这类格式符的价值所在。它们将格式化的“元信息”也参数化了使得C语言的格式化I/O在保持高效的同时具备了令人惊讶的灵活性。

相关新闻

DXVK 启动失败完整自救指南:Intel 驱动更新后游戏闪退,十分钟照此修复

DXVK 启动失败完整自救指南:Intel 驱动更新后游戏闪退,十分钟照此修复

DXVK 启动失败完整自救指南:Intel 驱动更新后游戏闪退,十分钟照此修复 【免费下载链接】dxvk Vulkan-based implementation of D3D8, 9, 10 and 11 for Linux / Wine 项目地址: https://gitcode.com/gh_mirrors/dx/dxvk 某个平平无奇的周五晚上&a…

2026/10/11 10:29:13 阅读更多 →
MOOTDX通达信数据接口实战指南:从零构建生产级量化数据管道

MOOTDX通达信数据接口实战指南:从零构建生产级量化数据管道

MOOTDX通达信数据接口实战指南:从零构建生产级量化数据管道 【免费下载链接】mootdx 通达信数据读取的一个简便使用封装 项目地址: https://gitcode.com/GitHub_Trending/mo/mootdx MOOTDX 是通达信数据接口的 Python 封装,把行情、历史、财务、板…

2026/10/11 10:25:03 阅读更多 →
告别文档下载烦恼:kill-doc这款免费工具一口气打通30+平台

告别文档下载烦恼:kill-doc这款免费工具一口气打通30+平台

告别文档下载烦恼:kill-doc这款免费工具一口气打通30平台 【免费下载链接】kill-doc 看到经常有小伙伴们需要下载一些免费文档,但是相关网站浏览体验不好各种广告,各种登录验证,需要很多步骤才能下载文档,该脚本就是为…

2026/10/7 12:53:27 阅读更多 →

最新新闻

如何看懂 Portabase 安全机制:AES-256-GCM凭据加密、RBAC与Passkey登录完整指南

如何看懂 Portabase 安全机制:AES-256-GCM凭据加密、RBAC与Passkey登录完整指南

【免费下载链接】portabase Portabase - Database backup & restore tool for PostgreSQL, MySQL, MsSQL, MariaDB, Firebird SQL, SQLite, MongoDB, Redis and Docker Volume 项目地址: https://gitcode.com/gh_mirrors/por/portabase 点击查看 免费下载 Por…

2026/10/11 13:09:49 阅读更多 →
Trace Labs OSINT VM 与 CTF:动手练习平台指南

Trace Labs OSINT VM 与 CTF:动手练习平台指南

Trace Labs OSINT VM 与 CTF:动手练习平台指南 【免费下载链接】Legendary_OSINT A list of OSINT tools & resources for (fraud-)investigators, CTI-analysts, KYC, AML and more. 项目地址: https://gitcode.com/GitHub_Trending/le/Legendary_OSINT …

2026/10/11 13:09:49 阅读更多 →
SSM+Layui图书管理系统实战:从架构选型到整合避坑

SSM+Layui图书管理系统实战:从架构选型到整合避坑

简介:基于SSMLayui的图书管理系统完整项目资源,面向Java Web初学者、毕业设计及课程设计人群,可解决图书增删改查、借阅归还、用户与权限管理等常见业务模块的开发难题。压缩包内含8个文件,共61.06MB,主要由Java源码压…

2026/10/11 13:09:49 阅读更多 →
SpringBoot校园综合服务系统:从数据库设计到部署排错全流程指南

SpringBoot校园综合服务系统:从数据库设计到部署排错全流程指南

最近帮人验收一套基于SpringBoot的校园平台综合服务系统,源码、部署文档、代码讲解三件套都说有,但真正拉起来跑的时候发现问题不少。这让我想好好聊聊这类项目该怎么做,以及源码、文档、部署这些“表面功夫”背后到底是什么。 所谓校园平台…

2026/10/11 13:09:49 阅读更多 →
双向LSTM与GRU实战:飞行轨迹预测选型与避坑指南

双向LSTM与GRU实战:飞行轨迹预测选型与避坑指南

简介:基于MATLAB开发的双向长短期记忆网络(LSTM)与门控循环单元(GRU)飞行轨迹预测代码包,主要面向具备本科及以上学历的科研人员、工程师和深度学习爱好者,可用于无人机、飞行器航迹预测、目标轨…

2026/10/11 13:09:49 阅读更多 →
Linux C++符号混淆实战:从符号泄露到崩溃还原

Linux C++符号混淆实战:从符号泄露到崩溃还原

上个月处理一个发布版Linux软件被逆向的排查,第一次动手就发现一个很扎心的现象:那个C项目没做任何符号层面的处理,对手一条nm命令下来,整个项目的内部函数名、类名、全局变量全部原样躺在那里。软件里有一块自研的核心算法&#…

2026/10/11 13:08:48 阅读更多 →

日新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 10:38:42 阅读更多 →