当前位置: C语言 -- 附录 -- freopen_s

freopen_s函数


概要:
#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
errno_t freopen_s(FILE * restrict * restrict newstreamptr,
      const char * restrict filename,
      const char * restrict mode,
      FILE * restrict stream);

描述:

该函数首先关闭先前与参数stream指向流相关联的文件,然后按参数mode指定的模式打开参数filename指向的文件,并将该文件与参数stream指向流相关联。关闭文件失败将被忽略。流的错误指示符(error indicator)和文件末尾指示符(end-of-file indicator)将被清除。

如果参数filename是空指针,函数就像使用当前关联文件一样,尝试将流的模式更改为参数mode指定的模式;哪些模式允许以及在什么情况下允许,将由实现定义。

如果成功打开文件,参数newstreamptr指向的FILE类型指针将被设置为参数stream的值;如果不成功,参数newstreamptr指向的FILE类型指针将被设置为空指针。


运行约束:

参数newstreamptrmodestream不能是空指针。

如果存在运行约束冲突,函数freopen_s既不会尝试关闭与参数stream相关联的文件,也不会尝试打开文件;此外如果参数newstreamptr不是空指针,函数将*newstreamptr设置为空指针。


参数:
FILE * restrict * restrict newstreamptr

指向FILE类型指针的指针。

const char * restrict filename

char类型指针,指向表示文件名的字符串(如果系统支持,文件名可以包含路径。),文件名规则由实现定义。

const char * restrict mode

char类型指针,指向的字符串表示文件访问模式。ISO/IEC 9899:2018标准支持的文件访问模式具体如下所示:

模式 描述
r 打开文本文件用于读取数据。
w 截断到零长度(如果文件已经存在的话。)或者创建新文本文件用于写入数据。
uw 截断到零长度(如果文件已经存在的话。)或者创建新文本文件用于写入数据,默认权限。
wx 创建新文本文件用于写入数据。
uwx 创建新文本文件用于写入数据,默认权限。
a 添加;打开或者创建文本文件用于在文件末尾处写入数据。
ua 添加;打开或者创建文本文件用于在文件末尾处写入数据,默认权限。
rb 打开二进制文件用于读取数据。
wb 截断到零长度(如果文件已经存在的话。)或者创建新二进制文件用于写入数据。
uwb 截断到零长度(如果文件已经存在的话。)或者创建新二进制文件用于写入数据,默认权限。
wbx 创建新二进制文件用于写入数据。
uwbx 创建新二进制文件用于写入数据,默认权限。
ab 添加;打开或者创建二进制文件用于在文件末尾处写入数据。
uab 添加;打开或者创建二进制文件用于在文件末尾处写入数据,默认权限。
r+ 打开文本文件用于更新数据(读取数据和写入数据)。
w+ 截断到零长度(如果文件已经存在的话。)或者创建新文本文件用于更新数据。
uw+ 截断到零长度(如果文件已经存在的话。)或者创建新文本文件用于更新数据,默认权限。
w+x 创建新文本文件用于更新数据。
uw+x 创建新文本文件用于更新数据,默认权限。
a+ 添加;打开或者创建文本文件用于更新数据,在文件末尾处写入数据。
ua+ 添加;打开或者创建文本文件用于更新数据,在文件末尾处写入数据,默认权限。
r+b或者rb+ 打开二进制文件用于更新数据(读取数据和写入数据)。
w+b或者wb+ 截断到零长度(如果文件已经存在的话。)或者创建新二进制文件用于更新数据。
uw+b或者uwb+ 截断到零长度(如果文件已经存在的话。)或者创建新二进制文件用于更新数据,默认权限。
w+bx或者wb+x 创建新二进制文件用于更新数据。
uw+bx或者uwb+x 创建新二进制文件用于更新数据,默认权限。
a+b或者ab+ 添加;打开或者创建二进制文件用于更新数据,在文件末尾处写入数据。
ua+b或者uab+ 添加;打开或者创建二进制文件用于更新数据,在文件末尾处写入数据,默认权限。

如果模式参数是除上表以外的其它值,函数行为是未定义的。

函数freopen_s和函数freopen的模式字符串基本一致,区别在于以'w'或者'a'开始的模式前可以存在'u'。


如果文件不存在或者文件无法读取,以读取模式(打开模式中存在r字符。)打开文件将会失败。

如果文件已经存在或者无法创建,以独占模式(打开模式中存在x字符。)打开文件将会失败。

底层系统可能在一定程度上支持独占访问权限,即进行写操作的文件以独占(非共享)的访问方式打开。创建文件时,如果模式字符串的第一个字符不是'u',文件应具有防止系统中的其它用户访问该文件的权限;如果模式字符串的第一个字符是'u',到文件关闭时该文件具有系统默认的文件访问权限,该权限与使用freopen函数创建的文件权限相同。

以添加模式打开文件(打开模式中存在a字符。)会导致对文件的所有后续写入都被强制到文件的当前末尾,而不管fseek函数的调用。由于空字符填充,在一些实现中以添加模式打开二进制文件(打开模式中存在b字符。)可能最初将流的文件位置指示符定位在最后写入的数据之外。

当以更新模式(打开模式中存在+字符。)打开文件时,可以在关联的流上执行输入和输出操作。在没有调用fflush函数或者文件定位函数(例如:fseekfsetposrewind函数。)的情况下,输出操作后不能立即执行输入操作;在没有调用文件定位函数的情况下,输入操作后不能立即执行输出操作,除非输入操作到达文件末尾(end-of-file)。在某些实现中,使用更新模式打开或者创建文本文件可能会打开或者创建二进制流。

FILE * restrict stream

FILE类型指针。


返回值:

如果成功打开文件,函数返回0;如果不能打开文件或者存在运行约束冲突,函数返回非0值。


范例:
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
/*安全函数freopen_s范例*/

#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    FILE *pFile;
    int ch;

    /*输出第一个文件的内容*/
    if(fopen_s(&pFile, "fileOne.txt", "r"))
        exit(EXIT_FAILURE);
    else
    {
        while((ch = fgetc(pFile)) != EOF)
            putchar(ch);
    }

    putchar('\n');

    /*输出第二个文件的内容。*/
    if(freopen_s(&pFile, "fileTwo.txt", "r", stdin))
        exit(EXIT_FAILURE);
    else
    {
        while((ch = fgetc(pFile)) != EOF)
            putchar(ch);
    }

    fclose(pFile);
    putchar('\n');

    return 0;
}


结果:

输出两个文件的内容。

注:使用Visual Studio编译。


相关内容:
fopen_s 打开文件的安全函数。