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

复用数组时使用memset后内容无法输出到文件的原因及解决方法

问题原因分析

1. feof循环条件误用

你当前的while (!feof(fit))是典型错误用法:C语言中feof仅在读取操作失败后才会置位,这意味着当fgets读到文件末尾返回NULL时,循环仍会执行一次。此时text中残留上一轮内容(或不确定值),xifrar_frase处理后生成的text_xifrat可能无效,进而导致输出异常或后续操作出错。

2. memset长度参数错误

代码中memset(text_xifrat, '\0', sizeof(text))存在隐患:如果text_xifrat的数组大小与text不一致(比如text_xifrat更小),这个操作会越界写入内存,破坏相邻变量(比如文件指针fit_x的内部结构),直接导致后续fprintf无法写入文件。

3. 加密函数可能未添加字符串终止符

如果xifrar_frase仅处理字符加密,未在text_xifrat的有效字符末尾添加'\0',那么text_xifrat不是合法的C字符串。此时fprintf会一直输出到内存中第一个'\0'为止,可能包含上一轮残留内容;而memset清空后,若加密函数仍未添加终止符,text_xifrat起始位置是'\0',自然无法输出有效内容。


解决方法

1. 修正循环条件

用fgets的返回值直接判断循环,避免feof的陷阱:

else{
    char text[MAX];
    char text_xifrat[MAX]; // 假设大小与text一致,根据实际情况调整
    while (fgets(text, MAX, fit) != NULL){
        xifrar_frase(text, m_clau, text_xifrat);
        // 确保text_xifrat是合法字符串后再输出
        fprintf(fit_x, "%s\n", text_xifrat);
        // 可选:清空数组(根据实际需求决定)
        memset(text, '\0', sizeof(text));
        memset(text_xifrat, '\0', sizeof(text_xifrat)); // 修正长度参数
    }
}

2. 修复memset的长度参数

清空text_xifrat时,必须使用其自身的大小:sizeof(text_xifrat),绝对不能复用text的大小,避免内存越界。

3. 确保加密函数生成合法字符串

修改xifrar_frase函数,在处理完所有字符后,手动添加字符串终止符。例如:

void xifrar_frase(const char *input, const char *key, char *output) {
    int i = 0;
    // 加密逻辑...
    // 处理完后添加终止符
    output[i] = '\0';
}

更优的数组清空方式

1. 无需每次清空(推荐)

对于字符串数组来说,大部分场景下不需要手动清空:

  • fgets会自动覆盖text的内容,并在末尾添加'\0',旧内容会被新的字符串终止符截断,不会影响后续处理。
  • 只要xifrar_frase保证text_xifrat以'\0'结尾,上一轮的残留内容会被终止符截断,fprintf只会输出当前加密的有效内容。

2. 必须清空时的高效方案

如果确实需要清空数组:

  • 使用memset:这是标准且高效的方式,但必须确保长度参数是数组的实际大小(仅当变量是数组名时,sizeof(arr)才会返回数组总字节数;如果是指针,需要手动传入数组长度)。
  • 局部数组初始化:如果是函数内的栈数组,可以在声明时直接初始化为全0:char text[MAX] = {0};,但此操作仅在声明时有效,循环中无法重复使用。
  • 避免使用bzero:它是BSD扩展函数,不属于C标准,兼容性差,不如memset通用。

内容的提问来源于stack exchange,提问作者Jan Torres Rodríguez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 06:40:26