You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在新文件名末尾追加单个字符?C程序输出不符预期求修正

问题分析与修正方案

核心问题梳理

  1. 非法修改命令行参数:直接对argv[1]执行strcat属于未定义行为,且后续循环会持续在已修改的文件名上追加内容,导致文件名不断变长(如filename_a→filename_ab)。
  2. 缓冲区类型错误:char *buf[size];是指针数组,而非用于存储字符的缓冲区,正确定义应为字符数组。
  3. 缺少字符串终止符:从文件读取单个字符后未添加\0,strcat会读取缓冲区后的垃圾数据,引发异常行为。
  4. 文件名拼接逻辑错误:每次循环应基于原始文件名重新构造目标文件名,而非在已修改的字符串上累加。

修正后的代码

#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>

int main(int argc, char *argv[]) {
    // 打开源文件,仅读模式足够
    int fd_src = open(argv[1], O_RDONLY);
    if (fd_src == -1) {
        return 1;
    }

    // 获取文件大小后,回到文件开头
    ssize_t size = lseek(fd_src, 0, SEEK_END);
    lseek(fd_src, 0, SEEK_SET);

    // 计算原始文件名长度,用于构造目标文件名
    size_t orig_name_len = strlen(argv[1]);
    // 文件名缓冲区:原始名 + "_" + 单个字符 + 终止符
    char filename[orig_name_len + 3];
    strcpy(filename, argv[1]);
    strcat(filename, "_");

    char buf[2]; // 存储单个字符 + 字符串终止符
    for (int i = 0; i < size; i++) {
        lseek(fd_src, i, SEEK_SET);
        read(fd_src, buf, 1);
        buf[1] = '\0'; // 手动添加终止符,保证字符串合法

        // 重置文件名的后缀部分,避免累加
        filename[orig_name_len + 1] = buf[0];
        filename[orig_name_len + 2] = '\0';

        // 创建并写入目标文件
        int fd_dest = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0644);
        if (fd_dest != -1) {
            write(fd_dest, buf, 1);
            close(fd_dest);
        }
    }

    close(fd_src);
    return 0;
}

关键修正说明

  • 不再修改argv[1],而是复制原始文件名到独立缓冲区,每次循环仅修改缓冲区的后缀部分,避免文件名累加。
  • 使用buf[2]存储读取的字符和终止符,确保字符串操作的合法性。
  • 通过orig_name_len精准控制文件名拼接位置,保证每次生成的文件名都是原始名_单个字符的格式。
  • 添加基础错误检查(如文件打开失败),提升程序健壮性。

内容的提问来源于stack exchange,提问作者Yasmin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 15:51:42