目录
1、将格式化数据输出到FILE *stream流基本型
(1)语法
(2)参数
(3)示例
2、将格式化数据输出到FILE *stream流并启用并启用在格式字符串中使用参数的顺序的规范
(1)语法
(2)参数
(3)示例
3、将格式化数据输出到FILE *stream流安全版本
(1)语法
(2)参数
(3)示例
C语言将格式化输出到FILE *stream流的函数的外观表达是以fprintf()为根的。将格式化输出到FILE *stream流的函数有:
1、将格式化数据输出到FILE *stream流基本型
fprintf、_fprintf_I、fwprintf、_fwprintf_I。
在VS2022 版本17.13.6上使用这些函数,会出现警告C6387。提示:“stream”可能是“0”: 这不符合函数“fprintf”的规范。比如:
警告 C6387 “stream”可能是“0”: 这不符合函数“fprintf”的规范。Test_fprintf_2 C:\Users\YCZN_MT\source\repos\Test_fprintf_2\Test_fprintf_2\Test_fprintf_2.c 21
解决的办法是:增加代码的鲁棒性,让逻辑更严谨。具体做法就是,增加空指针检查。
(1)语法
/**
fprintf 格式化一系列字符和值并将其输出到输出 stream。 每个 argument 函数(如果有)根据 format 中相应的格式规范进行转换和输出。 对于 fprintf,format 参数具有与 printf 中相同的语法。
fwprintf 是 fprintf 的宽字符版本;在 fwprintf 中,format 是宽字符字符串。 如果在 ANSI 模式下打开流,则这些函数行为相同。 fprintf 当前不支持到 UNICODE 流中的输出。
这些带有 _l 后缀的函数的版本相同,只不过它们使用传递的区域设置参数而不是当前线程区域设置。
*/
int fprintf(
FILE *stream,
const char *format [,
argument ]...
);
int _fprintf_l(
FILE *stream,
const char *format,
_locale_t locale [,
argument ]...
);
int fwprintf(
FILE *stream,
const wchar_t *format [,
argument ]...
);
int _fwprintf_l(
FILE *stream,
const wchar_t *format,
_locale_t locale [,
argument ]...
);
(2)参数
- stream:指向 FILE 结构的指针。
- format:窗体控件字符串。
- argument:可选参数。
- locale:要使用的区域设置。
- 返回值:
fprintf
返回已写入的字节数。fwprintf
返回已写入的宽字符数。其中每个函数在出现输出错误时返回一个负值。
(3)示例
// test_fprintf_2.c
/* This program uses fprintf to format various
* data and print it to the file named FPRINTF.OUT. It
* then displays FPRINTF.OUT on the screen using the system
* function to invoke the operating-system TYPE command.
*/
#include <stdio.h>
#include <process.h>
FILE* stream;
int main(void)
{
int i = 10;
double fp = 1.5;
char s[] = "this is a string";
char c = '\n';
fopen_s(&stream, "fprintf_2.out", "w");
fprintf(stream, "%s%c", s, c); //C6387
fprintf(stream, "%d\n", i);
fprintf(stream, "%f\n", fp);
fclose(stream); // C6387
system("type fprintf_2.out");
}
这段代码运行后会出现2处警告C6387,通过增加空指针检查,警告C6387消失:
// test_fprintf.c
/* This program uses fprintf to format various
* data and print it to the file named FPRINTF.OUT. It
* then displays FPRINTF.OUT on the screen using the system
* function to invoke the operating-system TYPE command.
*/
#include <stdio.h>
#include <process.h>
FILE* stream;
errno_t err;
int main(void)
{
int i = 10;
double fp = 1.5;
char s[] = "this is a string";
char c = '\n';
//err的作用:在调用 fclose 函数前添加空指针检查,可以避免警告 C6387
err = fopen_s(&stream, "fprintf.out", "w");
if (err != 0)
puts("文件打开失败\n");
else {
printf("文件打开成功\n"); //可以注释掉
if (stream != NULL)
{
fprintf(stream, "%s%c", s, c);
fprintf(stream, "%d\n", i);
fprintf(stream, "%f\n", fp);
fclose(stream);
}
}
system("type fprintf.out");
}
运行结果:
文件打开成功
this is a string
10
1.500000
C:\Users\YCZN_MT\Test_fprintf\x64\Debug\Test_fprintf.exe (进程 18692)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
2、将格式化数据输出到FILE *stream流并启用并启用在格式字符串中使用参数的顺序的规范
_fprintf_p、_fprintf_p_l、_fwprintf_p、_fwprintf_p_I。
(1)语法
/**
_fprintf_p 格式化一系列字符和值并将其输出到输出 stream。 每个 argument 函数(如果有)根据 format 中相应的格式规范进行转换和输出。 对于 _fprintf_p,format 参数具有与 _printf_p 中相同的语法。 这些函数支持位置参数,即可以更改格式字符串所使用的参数顺序。
_fwprintf_p 是 _fprintf_p 的宽字符版本;在 _fwprintf_p 中,format 是宽字符字符串。 如果在 ANSI 模式下打开流,则这些函数行为相同。 _fprintf_p 当前不支持到 UNICODE 流中的输出。
这些带有 _l 后缀的函数的版本相同,只不过它们使用传递的区域设置参数而不是当前区域设置。
*/
int _fprintf_p(
FILE *stream,
const char *format [,
argument ]...
);
int _fprintf_p_l(
FILE *stream,
const char *format,
_locale_t locale [,
argument ]...
);
int _fwprintf_p(
FILE *stream,
const wchar_t *format [,
argument ]...
);
int _fwprintf_p_l(
FILE *stream,
const wchar_t *format,
_locale_t locale [,
argument ]...
);
(2)参数
stream:
指向FILE
结构的指针。format:
窗体控件字符串。argument:
可选参数。locale:
要使用的区域设置。- 返回值:如果发生输出错误,则
_fprintf_p
和_fwprintf_p
返回写入的字符数或一个负值。 - _p:启用在格式字符串中使用参数的顺序的规范。按照“”内出现的参数顺序依次输出,参数顺序就是变量的排列序号。比如:("%2$s%1$c%3$d\n%4$f\n", c, s,i,fp),变量的排列序号依次是c=1,s=2,i=3,fp=4,“”内定义的参数输出顺序依次是:2、1、3、4,即s、c、i、fp。
(3)示例
// test_fprintf_p.c
// This program uses _fprintf_p to format various
// data and print it to the file named FPRINTF_P.OUT. It
// then displays FPRINTF_P.OUT on the screen using the system
// function to invoke the operating-system TYPE command.
//
#include <stdio.h>
#include <process.h>
int main(void)
{
FILE* stream = NULL;
int i = 10;
double fp = 1.5;
char s[] = "this is a string";
char c = '\n';
// Open the file
if (fopen_s(&stream, "fprintf_p.out", "w") == 0)
{
// Format and print data
_fprintf_p(stream, "%2$s%1$c", c, s); //在格式字符串中使用了参数顺序
_fprintf_p(stream, "%d\n", i); //此处应用等价于fprintf
_fprintf_p(stream, "%f\n", fp);
_fprintf_p(stream, "%2$s%1$c%3$d\n%4$f\n", c, s,i,fp); //在格式字符串中使用了参数顺序
_fprintf_p(stream, "%3$d\n%4$f\n%2$s%1$c", c, s,i,fp); //在格式字符串中使用了参数顺序
// Close the file
fclose(stream);
}
// Verify our data
system("type fprintf_p.out");
}
运行结果:
this is a string
10
1.500000
this is a string
10
1.500000
10
1.500000
this is a string
C:\Users\YCZN_MT\Test_fprinf_p\x64\Debug\Test_fprinf_p.exe (进程 21844)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
3、将格式化数据输出到FILE *stream流安全版本
fprintf_s、_fprintf_s_l、fwprintf_s、fwprintf_s_l。
(1)语法
/**
fprintf_s 格式化一系列字符和值并将其输出到输出 stream。 argument_list 中的每个参数(如果有)根据 format 中相应的格式规范进行转换和输出。 format 参数使用 printf 和 wprintf 函数的格式规范语法。
fwprintf_s 是 fprintf_s 的宽字符版本;在 fwprintf_s 中,format 是宽字符字符串。 如果在 ANSI 模式下打开流,则这些函数行为相同。 fprintf_s 当前不支持到 UNICODE 流中的输出。
这些带有 _l 后缀的函数的版本相同,只不过它们使用传递的区域设置参数而不是当前区域设置。
*/
int fprintf_s(
FILE *stream,
const char *format [,
argument_list ]
);
int _fprintf_s_l(
FILE *stream,
const char *format,
_locale_t locale [,
argument_list ]
);
int fwprintf_s(
FILE *stream,
const wchar_t *format [,
argument_list ]
);
int _fwprintf_s_l(
FILE *stream,
const wchar_t *format,
_locale_t locale [,
argument_list ]
);
(2)参数
- stream:指向 FILE 结构的指针。
- format:窗体控件字符串。
- argument_list:格式字符串的可选参数。
- locale:要使用的区域设置。
- 返回值:fprintf_s 返回已写入的字节数。 fwprintf_s 返回已写入的宽字符数。 其中每个函数在出现输出错误时返回一个负值。
(3)示例
// test_fprintf_s.c
// This program uses fprintf_s to format various
// data and print it to the file named FPRINTF_S.OUT. It
// then displays FPRINTF_S.OUT on the screen using the system
// function to invoke the operating-system TYPE command.
#include <stdio.h>
#include <process.h>
FILE* stream;
int main(void)
{
int i = 10;
double fp = 1.5;
char s[] = "this is a string";
char c = '\n';
errno_t err;
//err的作用:在调用 fclose 函数前添加空指针检查,可以避免警告 C6387
err = fopen_s(&stream, "fprintf_s.out", "w");
if (err != 0)
puts("文件打开失败\n");
else {
//printf("文件打开成功\n"); //可以注释掉
if (stream != NULL)
{
fprintf_s(stream, "%s%c", s, c);
fprintf_s(stream, "%d\n", i);
fprintf_s(stream, "%f\n", fp);
fclose(stream);
}
}
system("type fprintf_s.out");
}
运行结果:
this is a string
10
1.500000
C:\Users\YCZN_MT\Test_fprintf_s\x64\Debug\Test_fprintf_s.exe (进程 21396)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .