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

Ubuntu系统中fopen函数打开文件报错‘No such file or directory’求助

问题:fopen无法解析~路径导致文件打开失败,open函数却能正常工作

环境信息

  • 操作系统:Ubuntu 64位
  • 处理器:AMD Ryzen 7

问题描述

每次运行文件打开程序时,都会收到错误提示No such file or directory。已执行sudo apt-get install lib32z1,但问题仍未解决。

出错的fopen代码

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

void main(void)
{
    char* filename = "~/Documents/Manipulation/addresses.txt";
    
    printf("\nUsing fopen fuction");
    
    FILE* arch = fopen(filename, "r");

    if(arch == 0)
    {
      perror("fopen");
      printf("\n arch is null");
      exit(0);
    }
    else
    {
        printf("\n Arch is opened..");
    }
}

可正常工作的open代码

int fd;

printf("\nUsing open fuction");

fd = open ("addresses", O_RDONLY);
if(fd == 0)
{
    fprintf(stderr, "can't open %s: %s\n", filename, strerror(errno));
    exit(1);
}
else
{
    printf("\n Arch is opened..");
}

请问该如何解决这个问题?


解决方案

问题核心是**fopen不会自动解析路径中的~符号**,这个波浪号是shell(如bash)负责展开为用户主目录的,C标准库的文件操作函数不处理该逻辑。而open("addresses", O_RDONLY)能正常工作,是因为它用的是相对当前工作目录的路径,无需解析~。

提供三种解决方法:

  1. 直接使用绝对路径
    将~/Documents/Manipulation/addresses.txt替换为实际绝对路径,例如/home/你的用户名/Documents/Manipulation/addresses.txt。

  2. 手动通过环境变量拼接路径
    用getenv("HOME")获取用户主目录,再拼接成完整路径:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <errno.h>
    #include <fcntl.h>
    
    int main(void) // 注:main标准返回类型为int,不是void
    {
        const char* home = getenv("HOME");
        if (home == NULL) {
            perror("getenv");
            exit(EXIT_FAILURE);
        }
        char filename[256]; // 确保数组大小足够容纳路径
        snprintf(filename, sizeof(filename), "%s/Documents/Manipulation/addresses.txt", home);
        
        printf("\nUsing fopen function");
        
        FILE* arch = fopen(filename, "r");
    
        if(arch == NULL) // 用NULL代替0,语义更清晰
        {
          perror("fopen");
          printf("\n arch is null");
          exit(EXIT_FAILURE);
        }
        else
        {
            printf("\n Arch is opened..");
            fclose(arch); // 记得关闭文件,避免资源泄漏
        }
        
        return EXIT_SUCCESS;
    }
    
  3. 通过shell展开路径(不推荐)
    可以用system或popen调用shell展开路径,但这种方式复杂度高且存在安全风险,非必要不建议使用。

额外注意细节:

  • void main(void)不符合C标准,main函数应返回int类型;
  • 文件打开后务必调用fclose关闭,避免文件描述符泄漏;
  • 安装lib32z1的操作和当前问题无关,该问题是路径解析逻辑导致,并非32位库缺失。

内容的提问来源于stack exchange,提问作者César Espíndola

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 04:43:23