14 - fopen()函数

本文详细解析了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。

### 功能 fopen 函数主要用于打开一个文件并创建文件指针,同时为文件分配缓冲区,其返回一个指向该文件的 FILE 类型指针,能够让程序对文件进行读写等各种操作[^1][^3]。 ### 使用方法 以下是一个使用 fopen 函数的基本示例: ```c #include <stdio.h> int main() { FILE *filePtr; const char *filename = "example.txt"; const char *mode = "w"; // 尝试打开文件 filePtr = fopen(filename, mode); // 检查文件是否成功打开 if (filePtr == NULL) { perror("Error opening file"); return -1; } // 文件操作,例如写入一些内容到文件 fprintf(filePtr, "Hello, World!\n"); // 关闭文件 fclose(filePtr); return 0; } ``` 在上述代码中,首先定义了文件名和打开模式,然后使用 `fopen` 函数打开文件。若文件成功打开,`filePtr` 会指向文件;若失败,其值为 `NULL`。接着使用 `fprintf` 函数向文件写入内容,最后使用 `fclose` 函数关闭文件[^1]。 ### 注意事项 - **文件打开失败处理**:使用 `fopen` 时需检查其返回值,若返回 `NULL`,表示文件打开失败,可使用 `perror` 函数输出错误信息,避免后续操作因文件指针无效而导致程序崩溃[^1]。 - **VS2019 版本问题**:在 VS2019 中使用 `fopen` 会出现警告,提示该函数可能不安全,建议使用 `fopen_s` 替代。若仍想使用 `fopen`,可使用 `_CRT_SECURE_NO_WARNINGS` 来禁用此警告。示例代码如下: ```c #include <iostream> int main() { FILE* fp = NULL; // 使用 fopen_s 替代 fopen fopen_s(&fp,"D:\\study-C++\\test.txt", "w+"); fprintf(fp,"this is test\n"); fputs("test",fp); fclose(fp); return 0; } ``` 在上述代码中,将 `fopen` 替换为 `fopen_s`,并传入文件指针的地址,以确保在 VS2019 中正常使用文件操作功能[^2]。
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值