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

C语言读取文件到字符串并避免Core Dump错误问题排查

问题分析与修复方案

你的代码出现Core Dump的核心原因是未初始化指针file_name就直接写入,同时还有其他逻辑和安全问题,逐一说明并修复:

主要错误点

  • 野指针写入:char *file_name; 只声明指针但未分配内存或指向有效缓冲区,snprintf直接写入会触发段错误,这是Core Dump的根本原因。
  • 逻辑错误:调用read_file时固定传EXAMPLE_FILE,忽略了用户通过-f指定的自定义文件名。
  • 缓冲区初始化错误:char buffer[BUFFER_SIZE] = {"\0"}; 写法错误,字符串字面量不能用来初始化字符数组,应改为{0}清空缓冲区。
  • 缺少字符串终止符:fread不会自动在读取内容末尾添加'\0',直接打印会导致读取垃圾数据甚至越界。
  • getopt使用错误:依赖argv[2]获取选项参数不可靠,应该用getopt提供的optarg变量;默认分支的处理逻辑多余且错误。
  • 错误信息不完善:文件打开失败时仅打印"Warning!!!",没有输出具体错误原因,不利于调试。

修复后的完整代码

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>

#define BUFFER_SIZE 1024
#define EXAMPLE_FILE "programing_languages.example"
#define MAX_FILENAME_LEN 256  // 定义文件名缓冲区最大长度

int read_file(char *buffer, const char *file_name)
{
    FILE *file = fopen(file_name, "r");
    if (file == NULL)
    {
        perror("Failed to open file");  // 打印具体错误信息
        return 1;
    }

    // 读取文件内容,返回实际读取的字节数,预留一个字节给终止符
    size_t bytes_read = fread(buffer, sizeof(char), BUFFER_SIZE - 1, file);
    buffer[bytes_read] = '\0';  // 手动添加字符串终止符

    fclose(file);
    return 0;
}

int main(int argc, char *argv[])
{   
    int opt;
    int file_name_customized = 0;
    char file_name[MAX_FILENAME_LEN] = {0};  // 用固定大小数组替代野指针

    while ((opt = getopt(argc, argv, "f:")) != -1) {
        switch (opt) {
            case 'f':
                // 用snprintf确保不会缓冲区溢出,MAX_FILENAME_LEN作为上限
                snprintf(file_name, MAX_FILENAME_LEN, "%s", optarg);
                file_name_customized = 1;
                break;
            default:
                // 非法选项时使用默认文件名
                snprintf(file_name, MAX_FILENAME_LEN, EXAMPLE_FILE);
                break;
        }
    }

    // 未指定-f选项时使用默认文件名
    if (!file_name_customized)
    {
        snprintf(file_name, MAX_FILENAME_LEN, EXAMPLE_FILE);
    }

    char buffer[BUFFER_SIZE] = {0};  // 正确初始化缓冲区

    if (read_file(buffer, file_name) == 1)
    {
        fprintf(stderr, "Failed to open file: %s\n", file_name);
        return errno;
    }

    printf("File content:\n%s\n", buffer);
    return 0;
}

关键修复说明

  1. 解决野指针问题:将char *file_name;改为固定大小数组char file_name[MAX_FILENAME_LEN] = {0};,避免未初始化指针的非法内存访问。
  2. 修正文件名传递逻辑:调用read_file时传入file_name,确保使用用户指定或默认的文件名。
  3. 添加字符串终止符:fread时预留一个字节的空间,读取后手动添加'\0',保证缓冲区是合法的C字符串。
  4. 正确使用getopt:用optarg获取-f的参数,避免依赖argv索引的不可靠性;添加非法选项的处理逻辑。
  5. 完善错误处理:用perror打印系统错误信息,便于定位文件打开失败的原因;使用fprintf(stderr)输出错误到标准错误流,符合规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 03:43:29