首页 > 代码库 > fopen的使用小记
fopen的使用小记
整理自https://msdn.microsoft.com/zh-cn/library/t3ayayh1(VS.80).aspx
errno, _doserrno, _sys_errlist, and _sys_nerr
这些全局变量包含perror和strerror函数使用的错误代码来打印错误消息。 应该使用下表中列出的更安全的功能版本代替它们的全局变量。
Global Variable | Functional Equivalents |
---|---|
_doserrno |
_get_doserrno, _set_doserrno |
_errno |
_get_errno, _set_errno |
These variables are declared in STDLIB.H as
extern int _doserrno; extern int errno; extern char *_sys_errlist[ ]; extern int _sys_nerr;
系统级调用中的错误设置了errno。因为errno保留设置它的最后一次调用的值,所以该值可能会被后续调用所改变。始终在可能设置的呼叫之前和之后检查errno。
在错误中,errno不一定设置为与系统调用返回的错误代码相同的值。对于I / O操作,请使用_doserrno访问errno代码的操作系统错误代码。对于大多数非I / O操作,_doserrno的值未定义。
每个错误值都与可以使用perror打印或使用strerror存储在字符串中的错误消息相关联。 perror和strerror使用_sys_errlist数组和_sys_nerr(_sys_errlist中的元素数)来处理错误信息。
图书馆数学例程通过调用_matherr设置errno。为了处理数学错误,请根据_matherr参考描述编写自己的例程,并将其命名为_matherr。
在ERRNO.H中定义为预定义常量的所有errno值均与UNIX兼容,并在下面列出。只有ERANGE,EILSEQ和EDOM在ANSI标准中指定。
Constant | System error message | Value |
---|---|---|
EPERM |
Operation not permitted |
1 |
ENOENT |
No such file or directory |
2 |
ESRCH |
No such process |
3 |
EINTR |
Interrupted function |
4 |
EIO |
I/O error |
5 |
ENXIO |
No such device or address |
6 |
E2BIG |
Argument list too long |
7 |
ENOEXEC |
Exec format error |
8 |
EBADF |
Bad file number |
9 |
ECHILD |
No spawned processes |
10 |
EAGAIN |
No more processes or not enough memory or maximum nesting level reached |
11 |
ENOMEM |
Not enough memory |
12 |
EACCES |
Permission denied |
13 |
EFAULT |
Bad address |
14 |
EBUSY |
Device or resource busy |
16 |
EEXIST |
File exists |
17 |
EXDEV |
Cross-device link |
18 |
ENODEV |
No such device |
19 |
ENOTDIR |
Not a directory |
20 |
EISDIR |
Is a directory |
21 |
EINVAL |
Invalid argument |
22 |
ENFILE |
Too many files open in system |
23 |
EMFILE |
Too many open files |
24 |
ENOTTY |
Inappropriate I/O control operation |
25 |
EFBIG |
File too large |
27 |
ENOSPC |
No space left on device |
28 |
ESPIPE |
Invalid seek |
29 |
EROFS |
Read-only file system |
30 |
EMLINK |
Too many links |
31 |
EPIPE |
Broken pipe |
32 |
EDOM |
Math argument |
33 |
ERANGE |
Result too large |
34 |
EDEADLK |
Resource deadlock would occur |
36 |
EDEADLOCK |
Same as EDEADLK for compatibility with older Microsoft C versions |
36 |
ENAMETOOLONG |
Filename too long |
38 |
ENOLCK |
No locks available |
39 |
ENOSYS |
Function not supported |
40 |
ENOTEMPTY |
Directory not empty |
41 |
EILSEQ |
Illegal byte sequence |
42 |
STRUNCATE |
String was truncated |
80 |
备注:fopen有一个小坑,当然只对于初学者而言
fopen的方法定义是这样的
FILE *fopen(const char * __restrict __filename, const char * __restrict __mode) __DARWIN_ALIAS_STARTING(__MAC_10_6, __IPHONE_2_0, __DARWIN_ALIAS(fopen));
fopen有两个参数,一个是你要操作的文件名_filename,一个是你要做什么操作_mode,mode没有什么好说的,filename这个参数,如果只传你想操作的文件名,而你的文件是本地的,可能会因为路径问题,提示你找不到文件。error = 2(No such file or directory)没有相关路径或者没有这个文件。
这个情况有两种解决方案:
一种是本地利用w的mode自己去创建一个文件,针对这个文件去操作,可以保证这个文件是在你的当前目录下的,不过这种不一定适用,比如我就是要读一个字库的bin文件,然后想将字库文件中的Unicode字库点阵转成utf8,存到数组中,写入文件。
第二种比较简单,你可以尝试一下绝对路径,找到文件的绝对路径,给到参数_filename就OK了,需要注意的是,路径中一般都包含“\”字符,在C/C++语言中有转译字符这一说;
转义字符
|
意义
|
ASCII码值(十进制)
|
\a
|
响铃(BEL)
|
007
|
\b
|
退格(BS) ,将当前位置移到前一列
|
008
|
\f
|
换页(FF),将当前位置移到下页开头
|
012
|
\n
|
换行(LF) ,将当前位置移到下一行开头
|
010
|
\r
|
回车(CR) ,将当前位置移到本行开头
|
013
|
\t
|
水平制表(HT) (跳到下一个TAB位置)
|
009
|
\v
|
垂直制表(VT)
|
011
|
\\
|
代表一个反斜线字符‘‘\‘
|
092
|
\‘
|
代表一个单引号(撇号)字符
|
039
|
\"
|
代表一个双引号字符
|
034
|
\? |
代表一个问号 |
063 |
\0
|
空字符(NULL)
|
000
|
\ooo
|
1到3位八进制数所代表的任意字符
|
三位八进制
|
\xhh
|
1到2位十六进制所代表的任意字符
|
二位十六进制
|
1 #include <iostream> 2 #include <fstream> 3 4 int main () 5 { 6 std::cout << "hello world \n"; 7 8 FILE *fp; 9 char *ch = ""; 10 char buff[100]; 11 12 errno_t err = fopen_s(&fp,"c:\\Users\\zhi\\Desktop\\abc.txt","r"); 13 14 if(err == 0) 15 { 16 printf("the file open successful!"); 17 18 ch = fgets(buff,100,fp); 19 printf("ch is :%s",ch); 20 fclose(fp); 21 22 }else{ 23 printf("err:%d",err); 24 printf("the file open not OK!"); 25 } 26 return 0; 27 }
先整理这些,都是昨天遇到的问题,虽小却有成长.
fopen的使用小记