目录
2、格式化输出打印至stdout并启用在格式字符串中使用参数的顺序
格式化输出打印至stdout的函数是以printf()为根的,将格式化输出打印至标准输出流的函数有:
1、打印至标准输出流
将格式化输出打印至标准输出流printf、_printf_l、wprintf、_wprintf_l。
(1)语法
/**
printf 函数格式化一系列字符和值并将其输出到标准输出流 stdout。 如果自变量跟在 format 字符串后面,则 format 字符串必须包含确定自变量的输出格式的规范。 printf 和 fprintf 的行为相同,只不过 printf 会将输出写入到 stdout 而不是 FILE 类型的目标。
wprintf 是 printf 的宽字符版本;format 是宽字符字符串。 如果在 ANSI 模式下打开流,则 wprintf 和 printf 的行为相同。 printf 当前不支持到 UNICODE 流中的输出。
这些带有 _l 后缀的函数的版本相同,只不过它们使用传递的区域设置参数而不是当前线程区域设置。
format 自变量由普通字符、转义序列和(如果自变量遵循 format)格式规范组成。 将普通字符和转义序列按照其外观的顺序复制到 stdout。
*/
int printf(
const char *format [,
argument]...
);
int _printf_l(
const char *format,
_locale_t locale [,
argument]...
);
int wprintf(
const wchar_t *format [,
argument]...
);
int _wprintf_l(
const wchar_t *format,
_locale_t locale [,
argument]...
);
(2)参数
format:
设置控件格式。argument:
可选参数。locale:
要使用的区域设置。-
返回值:返回输出的字符数或负值(如果出错)。 如果
format
为NULL
,则会调用无效的参数处理程序,如参数验证中所述。 如果允许执行继续,则该函数将返回 -1 并将errno
设置为EINVAL
。 如果在argument
中遇到EOF
(0xFFFF),则该函数将返回 -1。
(3)示例
// printf.c
// This program uses the printf and wprintf functions
// to produce formatted output.
#include <stdio.h>
int main(void)
{
char ch = 'h',
* string = "computer";
wchar_t wch = L'w',
* wstring = L"Unicode";
int count = -9234;
double fp = 251.7366;
// Display integers
printf("Integer formats:\n"
" Decimal: %d Justified: %.6d "
"Unsigned: %u\n",
count, count, count);
// Display decimals
printf("Decimal %d as:\n Hex: %Xh "
"C hex: 0x%x Octal: %o\n",
count, count, count, count);
// Display in different radixes
printf("Digits 10 equal:\n Hex: %i "
"Octal: %i Decimal: %i\n",
0x10, 010, 10);
// Display characters
printf("Characters in field (1):\n"
"%10c%5hc%5C%5lc\n",
ch, ch, wch, wch);
wprintf(L"Characters in field (2):\n"
L"%10C%5hc%5c%5lc\n",
ch, ch, wch, wch);
// Display strings
printf("Strings in field (1):\n%25s\n"
"%25.4hs\n %S%25.3ls\n",
string, string, wstring, wstring);
wprintf(L"Strings in field (2):\n%25S\n"
L"%25.4hs\n %s%25.3ls\n",
string, string, wstring, wstring);
// Display real numbers
printf("Real numbers:\n %f %.2f %e %E\n",
fp, fp, fp, fp);
// Display pointer
printf("\nAddress as: %p\n", &count);
}
运行结果:
Integer formats:
Decimal: -9234 Justified: -009234 Unsigned: 4294958062
Decimal -9234 as:
Hex: FFFFDBEEh C hex: 0xffffdbee Octal: 37777755756
Digits 10 equal:
Hex: 16 Octal: 8 Decimal: 10
Characters in field (1):
h h w w
Characters in field (2):
h h w w
Strings in field (1):
computer
comp
Unicode Uni
Strings in field (2):
computer
comp
Unicode Uni
Real numbers:
251.736600 251.74 2.517366e+02 2.517366E+02
Address as: 00000034547FF804
C:\Users\pc\printf\TestPrintf\x64\Debug\TestPrintf.exe (进程 16672)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
2、格式化输出打印至stdout并启用在格式字符串中使用参数的顺序
将格式化的输出打印到标准输出流,并启用在格式字符串中使用参数的顺序的规范:
_printf_p、_printf_p_l、_wprintf_p、_wprintf_p_l。
(1)语法
/**
_printf_p 函数格式化一系列字符和值并将其输出到标准输出流 stdout。 如果自变量跟在 format 字符串后面,则 format 字符串必须包含确定自变量的输出格式的规范。
_printf_p 和 printf_s 之间的差异在于 _printf_p 支持位置参数,这允许指定格式字符串中使用参数的顺序。
_wprintf_p 是 _printf_p 的宽字符版本;如果在 ANSI 模式下打开流,则它们的行为相同。 _printf_p 当前不支持到 UNICODE 流中的输出。
这些带有 _l 后缀的函数的版本相同,只不过它们使用传递的区域设置参数而不是当前线程区域设置。
确保 format 不是用户定义的字符串。
如果 format 或 argument 是 NULL,或者格式字符串包含无效的格式字符,则 _printf_p 和 _wprintf_p 函数将调用无效参数处理程序,如参数验证中所述。 如果允许执行继续,则该函数将返回 -1 并将 errno 设置为 EINVAL。
*/
int _printf_p(
const char *format [,
argument]...
);
int _printf_p_l(
const char *format,
_locale_t locale [,
argument]...
);
int _wprintf_p(
const wchar_t *format [,
argument]...
);
int _wprintf_p_l(
const wchar_t *format,
_locale_t locale [,
argument]...
);
(2) 参数
- format:设置控件格式。
- argument:可选参数。
- locale:要使用的区域设置。
- 返回值:返回输出的字符数或负值(如果出错)。
-p函数位置参数的用法说明:
- 默认情况下,如果不存在位置格式,则位置函数的行为与非位置函数的行为相同。 在格式说明符开头使用 %n$ 可将位置参数指定为格式化,其中 n 是参数列表中要格式化的参数位置。 格式字符串之后,第一个参数的参数位置从 1 开始。 格式说明符的其余部分遵循与 printf 格式说明符相同的规则。
- 宽度和精度:可以使用 *n$ 指定位置参数作为宽度或精度说明符,其中 n 是参数列表中的宽度或精度参数。 宽度或精度值的位置必须紧跟 * 符号出现。*左边是位置参数,*右边依次是宽度参数和精度参数,其中,小数点后面的是精度参数。并且,当设置了精度参数后的宽度参数可能会无效。
(3)示例1
// printf_p.c
// This program uses the _printf_p and _wprintf_p
// functions to choose the order in which parameters
// are used.
#include <stdio.h>
int main(void)
{
// Positional arguments
_printf_p("Specifying the order: %2$s %3$s %1$s %4$s %5$s.\n",
"little", "I'm", "a", "tea", "pot");
// Resume arguments
_wprintf_p(L"Reusing arguments: %1$d %1$d %1$d %1$d\n", 10);
// Width argument
_printf_p("Width specifiers: %1$*2$s", "Hello\n", 10);
}
运行结果:
Specifying the order: I'm a little tea pot.
Reusing arguments: 10 10 10 10
Width specifiers: Hello
C:\Users\pc\printf\Test_Printf_p\x64\Debug\Test_Printf_p.exe (进程 11280)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
(4)示例2
// Test_printf_p.c : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <stdio.h>
int main()
{
int i = 1,
j = 2,
k = 3;
double x = 0.1,
y = 2.22,
z = 333.3333;
char * s1 = "abc",
* s2 = "def",
* s3 = "ghi";
//位置顺序就是自变量参数的顺序
_printf_p("%1$s %2$s\n", "November", "10");
//所使用的数字顺序不需要与自变量顺序匹配,按“”定义的打印顺序打印 ,
_printf_p("%2$s %1$s\n", "November", "10");
//与传统的格式字符串不同,位置参数可多次在格式字符串中使用
_printf_p("%1$d times %1$d is %2$d\n", 10, 100);
_printf_p("%1$d times %1$d is %2$d\n", 100, 10);
// If positional arguments are unspecified,
// normal input order is used.
_printf_p("%d %d %d\n", i, j, k);
// Positional arguments are numbers followed by a $ character.
_printf_p("%3$d %1$d %2$d\n", i, j, k);
// The same positional argument may be reused.
_printf_p("%1$d %2$d %1$d\n", i, j);
// The positional arguments may appear in any order.
_printf_p("%1$s %2$s %3$s\n", s1, s2, s3);
_printf_p("%3$s %1$s %2$s\n", s1, s2, s3);
// 以下测试宽度和精度:*左边是位置参数,*右边是宽度参数,小数点后面的是精度参数
// Precision and width specifiers must be int types.
_printf_p("%3$*5$f %2$.*4$f %1$*4$.*5$f\n", x, y, z, j, k);
_printf_p("%3$*5$f %2$.*4$f %1$.*5$f\n", x, y, z, j, k); //当有精度参数的时候,宽度参数可能无效
_printf_p("%1$*2$s\n", "Hello", 10); //宽度10
_printf_p("%2$*1$s\n", 10, "Hello"); //宽度10
}
运行结果:
November 10
10 November
10 times 10 is 100
100 times 100 is 10
1 2 3
3 1 2
1 2 1
abc def ghi
ghi abc def
333.333300 2.22 0.100
333.333300 2.22 0.100
Hello
Hello
C:\Users\YCZN_MT\source\repos\Test_printf_p\x64\Debug\Test_printf_p.exe (进程 20540)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .
3、打印至标准输出流的安全版本
将格式化输出打印至标准输出流,这些版本的 printf、_printf_l、wprintf、_wprintf_l 具有的安全增强功能:
printf_s、_printf_s_l、wprintf_s、_wprintf_s_l。
(1)语法
/**
printf_s 函数格式化一系列字符和值并将其输出到标准输出流 stdout。 如果自变量跟在 format 字符串后面,则 format 字符串必须包含确定自变量的输出格式的规范。
printf_s 和 printf 的一个主要区别在于,printf_s 检查格式字符串中的格式字符是否有效,而 printf 仅检查格式字符串是否为 null 指针。 如果任一检查失败,将调用无效参数处理程序,如参数验证中所述。 如果允许执行继续,则该函数将返回 -1 并将 errno 设置为 EINVAL。
printf_s 和 fprintf_s 的行为相同,只不过 printf_s 会将输出写入到 stdout 而不是 FILE 类型的目标。
wprintf_s 是 printf_s 的宽字符版本;format 是宽字符字符串。 如果在 ANSI 模式下打开流,则 wprintf_s 和 printf_s 的行为相同。 printf_s 当前不支持到 UNICODE 流中的输出。
这些带有 _l 后缀的函数的版本相同,只不过它们使用传递的区域设置参数而不是当前线程区域设置。
*/
int printf_s(
const char *format [,
argument]...
);
int _printf_s_l(
const char *format,
_locale_t locale [,
argument]...
);
int wprintf_s(
const wchar_t *format [,
argument]...
);
int _wprintf_s_l(
const wchar_t *format,
_locale_t locale [,
argument]...
);
(2)参数
format:
设置控件格式。argument:
可选参数。locale:
要使用的区域设置。-
返回值:返回输出的字符数或负值(如果出错)。
format
自变量由普通字符、转义序列和(如果自变量遵循 format
)格式规范组成。 将普通字符和转义序列按照其外观的顺序复制到 stdout
。
(3)示例
// printf_s.c
/* This program uses the printf_s and wprintf_s functions
* to produce formatted output.
*/
#include <stdio.h>
int main(void)
{
char ch = 'h';
const char* string = "computer";
int count = -9234;
double fp = 251.7366;
wchar_t wch = L'w'; //宽字节就是用2个字节来表示一个汉字或字符
const wchar_t * wstring = L"Unicode"; //加L在前面就令它成为宽字节常量
/* Display integers. */
printf_s("Integer formats:\n"
" Decimal: %d Justified: %.6d Unsigned: %u\n",
count, count, count);
printf_s("Decimal %d as:\n Hex: %Xh C hex: 0x%x Octal: %o\n",
count, count, count, count);
/* Display in different radixes. */
/* %d专用于表示有符号的十进制整数,而%i则能智能识别输入的基数,支持十进制、八进制及十六进制。*/
/* 用十进制数表达其它进制得的数值 */
printf_s("Digits 10 equal:\n Hex: %i Octal: %i Decimal: %i\n",
0x10, 010, 10);
/* Display characters. */
/* h短整数或单精度浮点数
l 长整数或双精度浮点数 */
printf_s("Characters in field (1):\n%10c%5hc%5C%5lc\n", ch, ch, wch, wch);
wprintf_s(L"Characters in field (2):\n%10C%5hc%5c%5lc\n", ch, ch, wch, wch);
/* Display strings. */
/* h短整数或单精度浮点数
l 长整数或双精度浮点数
%25.4hs,宽字符,占位25,只输出4个字符,不足的位用空格左补齐
%25.3ls,宽字符,占位25,只输出3个字符,不足的位用空格左补齐 */
printf_s("Strings in field (1):\n%25s\n%25.4hs\n %S%25.3ls\n",
string, string, wstring, wstring);
printf_s("Strings in field (1):\n%25s\n%25.8hs\n %S%25.7ls\n",
string, string, wstring, wstring);
wprintf_s(L"Strings in field (2):\n%25S\n%25.4hs\n %s%25.3ls\n",
string, string, wstring, wstring);
/* Display real numbers. */
printf_s("Real numbers:\n %f %.2f %e %E\n", fp, fp, fp, fp);
/* Display pointer. */
printf_s("\nAddress as: %p\n", &count);
}
运行结果:
Integer formats:
Decimal: -9234 Justified: -009234 Unsigned: 4294958062
Decimal -9234 as:
Hex: FFFFDBEEh C hex: 0xffffdbee Octal: 37777755756
Digits 10 equal:
Hex: 16 Octal: 8 Decimal: 10
Characters in field (1):
h h w w
Characters in field (2):
h h w w
Strings in field (1):
computer
comp
Unicode Uni
Strings in field (1):
computer
computer
Unicode Unicode
Strings in field (2):
computer
comp
Unicode Uni
Real numbers:
251.736600 251.74 2.517366e+02 2.517366E+02
Address as: 0000003FB2F7FAE4
C:\Users\pc\printf\Test_Printf_s\x64\Debug\Test_Printf_s.exe (进程 24328)已退出,代码为 0 (0x0)。
按任意键关闭此窗口. . .