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

C语言读取文件时文本开头出现异常字符的问题解决

问题:文件字符替换时开头出现异常字符

需求说明

从文件读取两个空格分隔的字母,再读取下一行文本,将文本中所有第一个字母替换为第二个字母,最终覆盖原文件。

输入示例

a x
abecedar avion nuca

需将字母a替换为x。

我编写的代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    FILE *in;
    in = fopen("in.txt", "r+");
    char litera1 = 0, litera2 = 0, s[100], aux[100] = "";

    fscanf(in, " %c", &litera1);
    fgetc(in);
    fscanf(in, " %c", &litera2);
    strcpy(aux, "");
    printf("%c %c\n", litera1, litera2);

    while (fscanf(in, "%s", aux) != EOF)
    {
        strcat(s, aux);
        strcat(s, " ");
    }
    s[strlen(s) - 1] = NULL;
    printf("%s\n", s);
    for (int i = 0; i < 9; i++)
        printf("%c\n", s[i]);

    for (int i = 0; i < strlen(s); i++)
    {
        if (s[i] == litera1)
            s[i] = litera2;
    }

    /*
    rewind(in);
    fprintf(in,"%s", s);    i have to overwrite in the same file
    fflush(in);
    fclose(in); */
    return 0;
}

运行输出

a x
@§@abecedar avion nuca
@
§
@
a
b
e
c
e
d

另外,我写的另一个大小写转换程序也有类似问题:转换功能正常,但文本开头出现⌡字符。逐字符排查后没找到原因,怀疑是换行处理的问题,求解决异常字符的方法。


问题根源与解决办法

1. 未初始化数组导致的垃圾字符

你定义了char s[100];但未初始化,数组默认填充内存中的随机垃圾值。strcat(s, aux)从s的随机初始位置开始拼接,直接导致开头出现异常字符。
解决: 初始化s为空字符串:char s[100] = "";

2. 换行与分隔符处理不当

你用fgetc(in)手动跳过空格,但第一行读完两个字母后,剩余的换行符未被正确处理,可能干扰后续读取。更可靠的方式是用fscanf一次性读取两个字符,它会自动跳过空格、换行等分隔符:

// 替换原有的fscanf和fgetc代码
fscanf(in, "%c %c", &litera1, &litera2);

3. 覆盖原文件的正确姿势

用r+模式打开文件时,直接rewind后写入可能因原文件与新内容长度不同导致残留。稳妥的流程是:

  • 读取所有内容到内存
  • 关闭文件
  • 用w模式重新打开文件,写入修改后的内容
  • 关闭文件

修正后的完整代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    FILE *in;
    in = fopen("in.txt", "r");
    if (!in) { // 增加文件打开失败判断
        perror("Failed to open file");
        return 1;
    }

    char litera1, litera2;
    char s[100] = ""; // 初始化空字符串
    char aux[100];

    // 一次性读取两个替换字符,自动跳过分隔符
    fscanf(in, "%c %c", &litera1, &litera2);
    printf("%c %c\n", litera1, litera2);

    // 读取第二行文本,用fgets保留原格式
    fgets(s, sizeof(s), in);
    // 去掉fgets可能读取的末尾换行符
    s[strcspn(s, "\n")] = '\0';

    printf("%s\n", s);
    for (int i = 0; s[i] != '\0' && i < 9; i++)
        printf("%c\n", s[i]);

    // 替换字符
    for (int i = 0; s[i] != '\0'; i++)
    {
        if (s[i] == litera1)
            s[i] = litera2;
    }

    // 关闭文件后重新打开写入
    fclose(in);
    in = fopen("in.txt", "w");
    if (!in) {
        perror("Failed to open file for writing");
        return 1;
    }
    // 写入完整内容(替换规则+修改后的文本)
    fprintf(in, "%c %c\n%s\n", litera1, litera2, s);
    fclose(in);

    return 0;
}

额外说明

  • 用fgets读取整行比fscanf("%s")更合适,后者会把空格当作分隔符拆分单词,破坏原文本格式。
  • 始终检查文件是否成功打开,避免空指针操作。
  • 局部数组未初始化会包含随机值,直接使用会导致不可预测的行为,这是C语言中常见的坑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 20:23:23