fopen函数失败原因分析以及分析原因的方法

概述:

最近在分析一个偶现的问题,偶现概率特别低,问题还在分析中。把分析的知识做个总结,后面再继续补充。

问题描述:

代码在调用Lua的require函数时发生异常,通过查看require的源码跟踪,发现该函数的fopen函数返回打开文件失败的异常,
下面就来总结下fopen打开文件出错可能有哪些原因,也许不全,欢迎补充。

函数介绍:

函数原型 FILE * fopen(const char * path,const char * mode); 
函数功能 打开一个文件
参数:   path [in] 名称   mode[in] 打开方式
返回值:文件顺利打开后,指向该流的文件指针就会被返回。如果文件打开失败则返回NULL,并把错误代码存在errno 中。 
注:这里只是简单介绍下函数功能和参数,具体参数意思此处不分析。

原因分析及方法

1 参数path问题, 路径不对fopen就会是返回失败。
分析:首先查看path文件是否存在,其次检查path的路径相对路径还是绝对路径?如果是相对路径再检查是否当前进程的目录会切换了,软件找不到文件了.
如 相对路径 FILE *fp = fopen("./test/1.txt", "r"); 
  绝对路径 FILE *fp = fopen("/mnt/text/1.txt", "r");
假如确定参数path没问题后,则可以排除文件不存在的路径问题。此时可以打印错误码errno来定位问题(这个后面介绍)。

2 参数mode问题,mode控制文件打开的方式,如果用户打开的方式超出了当前用户的权限,那么fopen也会返回失败,
此时应该检查当前用户的操作权限,也可以打印错误码errno来定位问题
如果当前用户仅仅只有读的权限而以读写的方式打开文件 FILE *fp = fopen("./test/1.txt", "W+")

3 检查程序中是否有句柄泄露的可能即频繁的调用fopen而没有fclose,这种情况的表象就是前面刚刚开始的时候可以open成功
过一段时间后,怎么都open不成功了,检查路径和权限都没有问题, 那此时就要检查下是否句柄泄露了。一般linux最多支持1000来个
句柄,打开太多不关,则其他的没法打开了

4 通过检查errno来分析定位问题, errno是一个int型的值,在errno.h中定义不需要自己定义。
可以通过strerror(errno)查看错误信息, errno是调试程序的一个重要方法。

注:errno 是记录系统的最后一次错误代码。

例如 
FILE *fp = NULL;
if ((fp =fopen("./test/1.txt", "r")) == NULL)
{
printf("open fail errno = %d reason = %s \n", errno, strerrno(errno));
}
需要指出的是这样加入printf出问题,那么分局errno是记录系统最后一次错误代码,则有可能得不到我们想要的错误码,反而误导
最好的办法就是
FILE *fp = NULL;
int errNum = 0;
if ((fp =fopen("./test/1.txt", "r")) == NULL)
{
errNum = errno;
printf("open fail errno = %d reason = %s \n", errNum, strerrno(errNum));
}

常见的errno错误码有以下这些:
#define EPERM 1 /* Operation not permitted */ 
  #define ENOENT 2 /* No such file or directory */
  #define ESRCH 3 /* No such process */
  #define EIO 5 /* I/O error */
  #define ENXIO 6 /* No such device or address */
  #define E2BIG 7 /* Argument list too long */
  #define ENOEXEC 8 /* Exec format error */
  #define EBADF 9 /* Bad file number */
  #define ECHILD 10 /* No child processes */


更多的请网上搜索, 这里就分析这些,后续有发现继续补充...

  • 19
    点赞
  • 76
    收藏
    觉得还不错? 一键收藏
  • 15
    评论
c语音信号时域分析项目代码通常包括以下几个步骤: 1. 引用头文件:首先需要引用合适的头文件,如stdio.h、stdlib.h、math.h等,以便后续使用各种函数。 2. 读入语音信号数据:使用C语言提供的文件读取函数,如fopen()和fread(),来读入语音信号的数据文件。可以将数据存储在数组中,每个元素表示一个采样点的数值。 3. 计算信号的时域特征:使用计算公式和算法,如均值、方差、能量等,对语音信号进行时域特征的计算。可以使用for循环遍历数组中的每个采样点,根据公式进行计算,并存储在相应的变量中。 4. 输出结果:使用相关函数,如printf(),将时域特征的计算结果进行输出,可以输出到屏幕上或存储至文件中。可以输出平均值、方差、能量等时域特征的数值。 5. 释放资源:在程序结束时,需要释放资源,如关闭所打开的文件、释放动态申请的内存等。 示例代码如下: ```c #include <stdio.h> #include <stdlib.h> int main() { FILE* fp; int i, size, sum = 0; float mean, variance, energy; // 打开语音信号数据文件 fp = fopen("voice_signal.txt", "r"); if (fp == NULL) { printf("文件打开失败!"); return -1; } // 读取语音信号数据 size = fread(signal, sizeof(int), 1000, fp); // 计算信号的时域特征 for(i = 0; i < size; i++){ sum += signal[i]; } mean = (float)sum / size; sum = 0; for(i = 0; i < size; i++){ sum += pow(signal[i] - mean, 2); } variance = (float)sum / size; sum = 0; for(i = 0; i < size; i++){ sum += pow(signal[i], 2); } energy = (float)sum / size; // 输出结果 printf("平均值:%f\n", mean); printf("方差:%f\n", variance); printf("能量:%f\n", energy); // 关闭文件 fclose(fp); return 0; } ``` 以上代码为简化版的示例,仅包含了简单的文件读取和时域特征计算,实际的项目中可能还需要其他功能,如数据预处理、可视化等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值