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

C语言解密写入文件时未预期插入换行的问题排查

解密文件时多余换行问题的修复

问题场景

运行解密函数将明文写入文件时,输出文件的倒数第二行多出一个原加密文件不存在的空行。练习限制仅能使用<stdio.h>、<stdlib.h>、<stdbool.h>头文件。

尝试移除fprintf(fit, "%s\n", text);中的\n后,所有行挤在一起,仅最后一行“Quevedo”单独成行。

原文件内容:

Soneto a una nariz
Erase un hombre a una nariz pegado
erase una nariz superlativa
erase una nariz sayon y escriba
era Ovidio Nason mas naridado
muchisima nariz tan fiera
que en la cara de Anas fuera delito
Quevedo

处理后异常内容:

Soneto a una nariz
Erase un hombre a una nariz pegado
erase una nariz superlativa
erase una nariz sayon y escriba
era Ovidio Nason mas naridado
muchisima nariz tan fiera
que en la cara de Anas fuera delito

Quevedo

相关代码片段

主循环代码

printf("Introdueix el nom de l'arxiu el qual vols desencriptar. Es creara l'arxiu Text_desxifrat.txt amb el contingut desencriptat\n");

scanf("%s", n_arxiu);
fit_x = fopen(n_arxiu, "r");
fit = fopen("Text_desxifrat.txt", "w");
if (fit_x == NULL) printf("Error en obrir el fitxer\n");
else{
    while (fgets(text_xifrat, MAX*2, fit_x) != NULL){
        desxifrar_frase(text_xifrat, m_clau, text);
        fprintf(fit, "%s\n", text);
        for (i = 0; (text[i] > 64 && text[i] < 91) || (text[i] == 32) || (text[i] > 48 && text[i] < 58); i++) text[i] = '\0';
        for (i = 0; (text_xifrat[i] > 64 && text_xifrat[i] < 91) || (text_xifrat[i] == 32) || (text_xifrat[i] > 48 && text_xifrat[i] < 58); i++) text_xifrat[i] = '\0';
    }
    fclose(fit_x);
    fclose(fit);
}

desxifrar_frase函数

void desxifrar_frase(char frase[], char matriu_x[][7], char frase_desxifrada[]){
    int i = 0, comptador = 0, fila, col;

    while (frase[i+1] > 64 && frase[i+1] < 91){
        fila = trobar_element(frase[i], true, matriu_x);
        col = trobar_element(frase[i+1], false, matriu_x);
        frase_desxifrada[comptador] = matriu_x[fila][col];
        comptador++;
        i+=2;
    }
}

trobar_element函数

int trobar_element(char element, bool fila, char matriu_x[][7]){
    bool trobat = false;
    int i = 0, valor;
    if (fila){
        while (!trobat){
            if (element == matriu_x[i][0]){
                valor = i;
                trobat = true;
            }
            i++;
        }
    }
    else{
        while (!trobat){
            if (element == matriu_x[0][i]){
                valor = i;
                trobat = true;
            }
            i++;
        }
    }
    return valor;
}

问题根源

  1. 解密字符串无终止符:desxifrar_frase处理完字符后未添加'\0',fprintf输出时会读取数组中残留的垃圾数据(如换行符)。
  2. 数组清空不彻底:原清空循环仅清除字母、空格、数字,遇到其他字符就停止,残留数据会干扰下一次输出。
  3. 强制添加换行符:fprintf每次强制加\n,未匹配原文件的换行结构,导致多余换行。

修复方案

1. 完善解密函数,添加字符串终止符

修改desxifrar_frase,确保解密后的字符串是合法C字符串,同时兼容非字母字符(如空格):

void desxifrar_frase(char frase[], char matriu_x[][7], char frase_desxifrada[]){
    int i = 0, comptador = 0, fila, col;

    while (frase[i] != '\0' && frase[i+1] != '\0') {
        // 仅处理成对的大写字母(匹配加密规则)
        if ((frase[i] > 64 && frase[i] < 91) && (frase[i+1] > 64 && frase[i+1] < 91)) {
            fila = trobar_element(frase[i], true, matriu_x);
            col = trobar_element(frase[i+1], false, matriu_x);
            frase_desxifrada[comptador] = matriu_x[fila][col];
            comptador++;
            i += 2;
        } else {
            // 直接复制空格(根据需求调整其他非字母字符的处理)
            if (frase[i] == 32) {
                frase_desxifrada[comptador] = ' ';
                comptador++;
            }
            i++;
        }
    }
    // 必须添加终止符
    frase_desxifrada[comptador] = '\0';
}

2. 彻底清空数组

替换原部分清空的循环,改为遍历整个数组长度清空(避免使用<string.h>的memset):

// 替换原清空text的循环
for (i = 0; i < MAX; i++) {
    text[i] = '\0';
}
// 替换原清空text_xifrat的循环
for (i = 0; i < MAX*2; i++) {
    text_xifrat[i] = '\0';
}

3. 匹配原文件换行逻辑

手动检查原读取行是否包含换行符,仅在对应位置添加换行,避免强制加\n:

desxifrar_frase(text_xifrat, m_clau, text);

// 检查原行是否有换行符
int has_newline = 0;
for (int j = 0; text_xifrat[j] != '\0'; j++) {
    if (text_xifrat[j] == '\n') {
        has_newline = 1;
        break;
    }
}
// 如果原行有换行,给解密后的字符串添加换行
if (has_newline) {
    int len = 0;
    while (text[len] != '\0') len++;
    if (len < MAX - 1) { // 避免数组越界
        text[len] = '\n';
        text[len + 1] = '\0';
    }
}
// 仅输出字符串,不再强制加换行
fprintf(fit, "%s", text);

修复效果

修改后,输出文件的换行结构将与原文件完全一致,不会出现多余空行。

内容的提问来源于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.04 14:21:00