14 - fopen()函数

1 函数原型

fopen():打开文件,函数原型如下:

FILE * fopen ( const char * filename, const char * mode );

cstdio库描述如下:

Open file
1. Opens the file whose name is specified in the parameter filename and associates it with a stream that can be identified in future operations by the FILE pointer returned.
2. The operations that are allowed on the stream and how these are performed are defined by the mode parameter.
3. The returned stream is fully buffered by default if it is known to not refer to an interactive device .
4. The returned pointer can be disassociated from the file by calling fclose or freopen. All opened files are automatically closed on normal program termination.
5. The running environment supports at least FOPEN_MAX files open simultaneously.
  1. 打开文件和创建文件流是同一过程的不同方面:
    (1)打开文件是在操作系统层面获取对文件的访问权限;
    (2)创建文件流是在程序中创建对文件的抽象访问接口;
    (3)打开文件和创建文件流是同时进行的;当使用fopen()函数打开文件的同时会创建一个和文件相关联的文件流;通过文件流,使用文件操作函数便可操作文件(包括读文件、写文件和关闭文件等)。
  2. 文件指针和文件流是同一事物的不同表述方式:
    (1)打开文件成功后会返回一个指针FILE结构的文件指针;
    (2)文件指针唯一地标识文件流;
    (3)操作文件指针就是操作文件流;

2 参数

fopen()函数有两个参数filename和mode:

  1. 参数filename是个字符串,类型为char*;filename是要打开文件的文件名;
  2. 参数mode是个字符串,类型为char*;mode指定打开文件的模式。

cstdio库描述如下:

filename
1. C string containing the name of the file to be opened.
2. Its value shall follow the file name specifications of the running environment and can include a path (if supported by the system).

mode
1. C string containing a file access mode.

2.1 文件名

文件名(filename)可以包含文件路径:

  1. 文件路径指定了文件在文件系统中的位置,它可以是相对路径,也可以是绝对路径;相对路径是从当前目录开始到文件位置的路径,绝对路径是从根目录开始到文件位置的完整路径;
  2. 在Windows系统中,路径分隔符为反斜杠’\‘,然而反斜杠’\‘在字符串中表示转义序列的开始,因此需要使用两个反斜杠’\\‘来表示一个反斜杠’\'。

注意 在VS2019开发环境下,相对路径是以项目文件(.vcxproj)所在的目录为起点的。

2.2 模式

模式(mode)指定:

  1. 文件是以文本模式打开还是以二进制模式打开;
  2. 文件是只读、只写还是可读写。

2.2.1 文本模式

以文本模式打开文件,可用模式有"r"、“w”、“a”、“r+”、“w+”、“r+”,如下图所示:
在这里插入图片描述

2.2.2 二进制模式

以二进制模式打开文件,可用模式有"rb"、“wb”、“ab”、“r+b”/“rb+”、“w+b”/“wb+”、“r+b”/“rb+”,cstdio库描述如下:

1. With the mode specifiers above the file is open as a text file. 
2. In order to open a file as a binary file, a "b" character has to be included in the mode string. 
3. This additional "b" character can either be appended at the end of the string (thus making the following compound modes: "rb", "wb", "ab", "r+b", "w+b", "a+b") or be inserted between the letter and the "+" sign for the mixed modes ("rb+", "wb+", "ab+").

2.2.3 模式区别

文本模式和二进制模式区别如下:

  1. 以文本模式打开文件,意味着将打开的文件看作是文本文件,以文本流的方式处理文件;
  2. 以二进制模式打开文件,意味着将打开的文件看作是二进制文件,以二进制流的方式处理文件。

特别注意

  1. 以文本模式可以打开文本文件;以文本模式打开二进制文件是不推荐的,因为可能导致数据损坏或读取错误;
  2. 以二进制模式可以打开文本文件或二进制文件;
  3. 文本模式和二进制模式、文本流和二进制流、文本文件和二进制文件,三组概念组内有区别,组间有联系。

cstdio库描述如下:

1. Text files are files containing sequences of lines of text. 
2. Depending on the environment where the application runs, some special character conversion may occur in input/output operations in text mode to adapt them to a system-specific text file format.
3. Although on some environments no conversions occur and both text files and binary files are treated the same way, using the appropriate mode improves portability.

2.2.4 模式特性

  1. 以"r"和"r+"模式打开文件,文件必须存在;注意,"r+"模式写文件会覆盖原有数据;
  2. 以"w"和"w+"模式打开文件,如果文件存在,会清空文件已有内容,需谨慎操作;
  3. 以"a"和"a+"模式打开文件,写文件时文件定位操作被忽略,新写入数据总是附加至文末尾;
  4. 以读写模式"+"打开文件,对于写后读和读后写,需要刷新输出缓冲区或重定位文件。

cstdio库描述如下:

1. For files open for update (those which include a "+" sign), on which both input and output operations are allowed, the stream shall be flushed (fflush) or repositioned (fseek, fsetpos, rewind) before a reading operation that follows a writing operation. 
2. The stream shall be repositioned (fseek, fsetpos, rewind) before a writing operation that follows a reading operation (whenever that operation did not reach the end-of-file).

2.2.5 模式示例

2.2.5.1 以"r"模式打开

以"r"模式打开文件"1.txt",示例代码如下所示:

int main()
{
   //
   FILE* fp = NULL;
   //
   if ((fp = fopen("1.txt", "r")) == NULL)
   {
      perror("Failed to open file in \"r\" mode ");
      exit(1);
   }
   else
   {
      printf("Success to open file in \"r\" mode.\n");
      fclose(fp);
   }
   //
   return 0;
}

当文件不存在时,在"r"模式下,打开文件失败,代码运行结果如下图所示:

在这里插入图片描述

当文件存在时,在"r"模式下,打开文件成功,代码运行结果如下图所示:

在这里插入图片描述

2.2.5.2 以"w"模式打开

以"w"模式打开文件"2.txt",示例代码如下所示:

int main()
{
   //
   FILE* fp = NULL;
   //
   if ((fp = fopen("2.txt", "w")) == NULL)
   {
      perror("Failed to open file in \"w\" mode ");
      exit(1);
   }
   else
   {
      printf("Success to open file in \"w\" mode.\n");
      for (int i = 0; i < 10; i++)
      {
         fputc('a', fp);
      }
      fclose(fp);
   }
   //
   return 0;
}

当文件不存在时,在"w"模式下,创建文件,往文件中写入10个a,代码运行结果如下图所示:

在这里插入图片描述

在这里插入图片描述

当文件存在时,在"w"模式下,清空文件,修改代码,往文件中写入5个b,代码运行结果如下图所示:

在这里插入图片描述
在这里插入图片描述

2.2.5.3 以"a"模式打开

以"a"模式打开文件"3.txt",示例代码如下所示:

int main()
{
   //
   FILE* fp = NULL;
   //
   if ((fp = fopen("3.txt", "a")) == NULL)
   {
      perror("Failed to open file in \"a\" mode ");
      exit(1);
   }
   else
   {
      printf("Success to open file in \"a\" mode.\n");
      for (int i = 0; i < 10; i++)
      {
         fputc('a', fp);
      }
      fclose(fp);
   }
   //
   return 0;
}

当文件不存在时,在"a"模式下,创建文件,往文件中写入10个a,代码运行结果如下图所示:

在这里插入图片描述

在这里插入图片描述

当文件存在时,在"a"模式下,修改代码,往文件中写入10个b,新写入的数据被附加至文件末尾,代码运行结果如下图所示:

在这里插入图片描述

在这里插入图片描述

2.2.5.4 以"r+"模式打开

以"r+“模式打开文件"4.txt”,示例代码如下所示:

int main()
{
   //
   FILE* fp = NULL;
   //
   if ((fp = fopen("4.txt", "r+")) == NULL)
   {
      perror("Failed to open file in \"r+\" mode ");
      exit(1);
   }
   else
   {
      printf("Success to open file in \"r+\" mode.\n");
      for (int i = 0; i < 10; i++)
      {
         fputc('a', fp);
      }
      fclose(fp);
   }
   //
   return 0;
}

当文件不存在时,在"r+"模式下,打开文件失败,代码运行结果如下图所示:

在这里插入图片描述

当文件存在时,在"r+"模式下,文件初始内容为20个b,往文件中写入10个a,新写入的数据从头开始覆盖原有的数据,代码运行结果如下图所示:

在这里插入图片描述

在这里插入图片描述

2.2.5.5 以"w+"模式打开

以"w+“模式打开文件"5.txt”,示例代码如下所示:

int main()
{
   //
   FILE* fp = NULL;
   //
   if ((fp = fopen("5.txt", "w+")) == NULL)
   {
      perror("Failed to open file in \"w+\" mode ");
      exit(1);
   }
   else
   {
      printf("Success to open file in \"w+\" mode.\n");
      for (int i = 0; i < 10; i++)
      {
         fputc('a', fp);
      }
      fclose(fp);
   }
   //
   return 0;
}

当文件不存在时,在"w+"模式下,创建文件,往文件中写入10个a,代码运行结果如下图所示:

在这里插入图片描述

在这里插入图片描述

当文件存在时,在"w+"模式下,清空文件,修改代码,往文件中写入5个b,代码运行结果如下图所示:

在这里插入图片描述

在这里插入图片描述

2.2.5.6 以"a+"模式打开

以"a+“模式打开文件"6.txt”,示例代码如下所示:

int main()
{
   //
   FILE* fp = NULL;
   //
   if ((fp = fopen("6.txt", "a+")) == NULL)
   {
      perror("Failed to open file in \"a+\" mode ");
      exit(1);
   }
   else
   {
      printf("Success to open file in \"a+\" mode.\n");
      for (int i = 0; i < 10; i++)
      {
         fputc('a', fp);
      }
      fclose(fp);
   }
   //
   return 0;
}

当文件不存在时,在"a+"模式下,创建文件,往文件中写入10个a,代码运行结果如下图所示:

在这里插入图片描述

在这里插入图片描述

当文件存在时,在"a+"模式下,修改代码,往文件中写入10个b,新写入的数据被附加至文件末尾,代码运行结果如下图所示:

在这里插入图片描述

在这里插入图片描述

3 返回值

fopen()的返回值类型是FILE*类型:

  1. 打开文件成功,则返回一个指向FILE类型结构的指针;
  2. 打开文件失败,如文件不存在或没有足够的权限,则返回NULL。

cstdio库描述如下:

1. If the file is successfully opened, the function returns a pointer to a FILE object that can be used to identify the stream on future operations.
2. Otherwise, a null pointer is returned.
3. On most library implementations, the errno variable is also set to a system-specific error code on failure.

注意 使用fopen()函数打开文件后,一定要判断返回值是否为NULL。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值