本篇介绍stdio.h头文件中安全函数学习之printf_s,fprintf_s,scanf_s,fscanf_s,sprintf_s,_snprintf_s,sscanf_s。
实验环境: window11, VS2022
printf / printf_s example
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <locale.h>
#include <wchar.h>
#include <limits.h>
#include <inttypes.h>
#include <stdint.h>
#pragma warning(disable:4996)
int main(void)
{
const char* s = "Hello";
int ret = printf("字符串745675765:\n"); // 同 puts("字符串"); ret返回的输入字符的个数
printf(" 填充:ret=%d\n", ret);
printf("\t[%10s]\n", s);
printf("\t[%-10s]\n", s);
printf("\t[%*s]\n", 10, s);
printf(" 截断:\n");
printf("\t%.4s\n", s);
printf("\t%.*s\n", 3, s);
printf("字符:\t%c %%\n", 'A');
printf("整数:\n");
printf("\t十进制:\t\t%i %d %.6i %i %.0i %+i %i\n", 1, 2, 3, 0, 0, 4, -4);
printf("\t十六进制:\t%x %x %X %#x\n", 5, 10, 10, 6);
printf("\t八进制:\t\t%o %#o %#o\n", 10, 10, 4);
printf("浮点:\n");
printf("\t舍入:\t\t%f %.0f %.32f\n", 1.5, 1.5, 1.3);
printf("\t填充:\t\t%05.2f %.2f %5.2f\n", 1.5, 1.5, 1.5);
printf("\t科学表示:\t%E %e\n", 1.5, 1.5);
printf("\t十六进制:\t%a %A\n", 1.5, 1.5);
//printf("\t特殊值:\t\t0/0=%g 1/0=%g\n", 0.0 / 0.0, 1.0 / 0.0);
printf("定宽类型:\n");
printf("\t最大的 32 位值是 %" PRIu32 " 或 %#" PRIx32 "\n", UINT32_MAX, UINT32_MAX);
//printf_s() example
const char* ss = "Hello printf_s";
int rets = printf_s("printf_s 字符串:\n"); // 同 puts("字符串"); ret返回的输入字符的个数
printf_s(" 填充:ret=%d\n", rets);
printf_s("\t[%10s]\n", ss);
printf_s("\t[%-10s]\n", ss);
printf_s("\t[%*s]\n", 10, ss);
printf_s(" 截断:\n");
printf_s("\t%.4s\n", ss);
printf_s("\t%.*s\n", 3, ss);
printf_s("printf_s 字符:\t%c %%\n", 'A');
printf_s("printf_s 整数:\n");
printf_s("\t十进制:\t\t%i %d %.6i %i %.0i %+i %i\n", 1, 2, 3, 0, 0, 4, -4);
printf_s("\t十六进制:\t%x %x %X %#x\n", 5, 10, 10, 6);
printf_s("\t八进制:\t\t%o %#o %#o\n", 10, 10, 4);
printf_s("printf_s 浮点:\n");
printf_s("\t舍入:\t\t%f %.0f %.32f\n", 1.5, 1.5, 1.3);
printf_s("\t填充:\t\t%05.2f %.2f %5.2f\n", 1.5, 1.5, 1.5);
printf_s("\t科学表示:\t%E %e\n", 1.5, 1.5);
printf_s("\t十六进制:\t%a %A\n", 1.5, 1.5);
//printf("\t特殊值:\t\t0/0=%g 1/0=%g\n", 0.0 / 0.0, 1.0 / 0.0);
printf("printf_s 定宽类型:\n");
printf("\t最大的 32 位值是 %" PRIu32 " 或 %#" PRIx32 "\n", UINT32_MAX, UINT32_MAX);
return 0;
}
运行结果:
参考:
https://zh.cppreference.com/w/c/io/fprintf
https://www.standards.wiki/c/c_library_stdio_function_printf.html
https://www.standards.wiki/c/c_appendix_secure_function_printf_s.html
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/printf-printf-l-wprintf-wprintf-l?view=msvc-170
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/printf-s-printf-s-l-wprintf-s-wprintf-s-l?view=msvc-170
fprintf / fprintf_s example
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <locale.h>
#include <wchar.h>
#include <limits.h>
#include <inttypes.h>
#include <stdint.h>
#pragma warning(disable:4996)
int main(void)
{
int number = 0; //统计输出的字符数。
const char arr[] = "Problems are not stop signs, they are guidelines.";
fprintf(stdout, "%s%lld\n", arr, sizeof arr);
fprintf(stdout, "Characters written to the output stream: %d\n", number);
int i = 10;
double fp = 1.5;
char s[] = "this is a string";
char c = '\n';
FILE* stream;
fopen_s(&stream, "fprintf_s.out", "w");
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");
return 0;
}
运行结果:
参考:
https://zh.cppreference.com/w/c/io/fprintf
https://www.standards.wiki/c/c_library_stdio_function_fprintf.html
https://www.standards.wiki/c/c_appendix_secure_function_fprintf_s.html
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/fprintf-s-fprintf-s-l-fwprintf-s-fwprintf-s-l?view=msvc-170
scanf / scanf_s example
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <locale.h>
#include <wchar.h>
#include <limits.h>
#include <inttypes.h>
#include <stdint.h>
#pragma warning(disable:4996)
int main(void)
{
int count;
char str[100];
scanf("%[ ,.abcdefghijklmnopqrstuvwxyz\
ABCDEFGHIGKLMNOPQRSTUVWXYZ]%n", str, &count);
printf("The number of characters read from stdin: %d\n", count);
int i, result;
float fp;
char c, s[80];
wchar_t wc, ws[80];
result = scanf_s("%d %f %c %C %s %S", &i, &fp, &c, 1,
&wc, 1, s, (unsigned)_countof(s), ws, (unsigned)_countof(ws));
printf("The number of fields input is %d\n", result);
printf("The contents are: %d %f %c %C %s %S\n", i, fp, c, wc, s, ws);
return 0;
}
运行结果:
参考:
https://zh.cppreference.com/w/c/io/fscanf
https://www.standards.wiki/c/c_library_stdio_function_scanf.html
https://www.standards.wiki/c/c_appendix_secure_function_scanf_s.html
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/fprintf-s-fprintf-s-l-fwprintf-s-fwprintf-s-l?view=msvc-170
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/scanf-s-scanf-s-l-wscanf-s-wscanf-s-l?view=msvc-170
fscanf / fscanf_s example
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <locale.h>
#include <wchar.h>
#include <limits.h>
#include <inttypes.h>
#include <stdint.h>
#pragma warning(disable:4996)
int main(void)
{
FILE* pFile;
int number;
int state;
pFile = fopen("./gch.txt", "r"); // gch.txt的内容为 101 0x101 -0101
while (!feof(pFile))
{
state = fscanf(pFile, "%i", &number);
if (state > 0)
printf("%d\n", number);
else
break;
}
fclose(pFile);
//fscanf_s example
FILE* stream;
long l;
float fp;
char s[81];
char c;
errno_t err = fopen_s(&stream, "fscanf.out", "w+");
if (err)
printf_s("The file fscanf.out was not opened\n");
else
{
fprintf_s(stream, "%s %ld %f%c", "a-string", 65000, 3.14159, 'x');
// Set pointer to beginning of file:
fseek(stream, 0L, SEEK_SET);
// Read data back from file:
fscanf_s(stream, "%s", s, _countof(s));
fscanf_s(stream, "%ld", &l);
fscanf_s(stream, "%f", &fp);
fscanf_s(stream, "%c", &c, 1);
// Output data read:
printf("%s\n", s);
printf("%ld\n", l);
printf("%f\n", fp);
printf("%c\n", c);
fclose(stream);
}
return 0;
}
运行结果:
参考:
https://zh.cppreference.com/w/c/io/fscanf
https://www.standards.wiki/c/c_library_stdio_function_fscanf.html
https://www.standards.wiki/c/c_appendix_secure_function_fscanf_s.html
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/fscanf-fscanf-l-fwscanf-fwscanf-l?view=msvc-170
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/fscanf-s-fscanf-s-l-fwscanf-s-fwscanf-s-l?view=msvc-170
sprintf / sprintf_s example
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <locale.h>
#include <wchar.h>
#include <limits.h>
#include <inttypes.h>
#include <stdint.h>
#pragma warning(disable:4996)
int main(void)
{
char str[100];
const char arr[] = "Practice makes perfect.";
sprintf(str, "%s", arr);
puts(str);
//sprintf_s example
char buffer[200], s[] = "computer", c = 'l';
int i = 35, j;
float fp = 1.7320534f;
// Format and print various data:
j = sprintf_s(buffer, 200, " String: %s\n", s);
j += sprintf_s(buffer + j, 200 - j, " Character: %c\n", c);
j += sprintf_s(buffer + j, 200 - j, " Integer: %d\n", i);
j += sprintf_s(buffer + j, 200 - j, " Real: %f\n", fp);
printf_s("Output:\n%s\ncharacter count = %d\n", buffer, j);
return 0;
}
运行结果:
参考:
https://zh.cppreference.com/w/c/io/fprintf
https://www.standards.wiki/c/c_library_stdio_function_sprintf.html
https://www.standards.wiki/c/c_appendix_secure_function_sprintf_s.html
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/sprintf-sprintf-l-swprintf-swprintf-l-swprintf-l?view=msvc-170
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/sprintf-s-sprintf-s-l-swprintf-s-swprintf-s-l?view=msvc-170
snprintf / snprintf_s example
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <locale.h>
#include <wchar.h>
#include <limits.h>
#include <inttypes.h>
#include <stdint.h>
#pragma warning(disable:4996)
int main(void)
{
char str[100];
const char arr[] = "Easier said than done.";
snprintf(str, 13, "%s", arr);
puts(str);
//_snprintf_s example
char str_s[100];
const char arr_s[] = "All roads lead to Rome.";
_snprintf_s(str_s, sizeof(str_s) / sizeof(str_s[0]), "%s", arr_s);
puts(str_s);
return 0;
}
运行结果:
参考:
https://zh.cppreference.com/w/c/io/fprintf
https://www.standards.wiki/c/c_library_stdio_function_snprintf.html
https://www.standards.wiki/c/c_appendix_secure_function_snprintf_s.html
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/snprintf-snprintf-snprintf-l-snwprintf-snwprintf-l?view=msvc-170
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/snprintf-s-snprintf-s-l-snwprintf-s-snwprintf-s-l?view=msvc-170
sscanf / sscanf_s example
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <locale.h>
#include <wchar.h>
#include <limits.h>
#include <inttypes.h>
#include <stdint.h>
#pragma warning(disable:4996)
int main(void)
{
const char str[] = "123a456";
int number;
int count;
sscanf(str, "%d%*c%n", &number, &count);
printf("number: %d\n", number);
printf("characters read from the array: %d\n", count);
//sscanf_s example
char tokenstring[] = "15 12 14...";
char s[81];
char c;
int i;
float fp;
// Input various data from tokenstring:
// max 80 character string plus null terminator
sscanf_s(tokenstring, "%s", s, (unsigned)_countof(s));
sscanf_s(tokenstring, "%c", &c, (unsigned)sizeof(char));
sscanf_s(tokenstring, "%d", &i);
sscanf_s(tokenstring, "%f", &fp);
// Output the data read
printf_s("String = %s\n", s);
printf_s("Character = %c\n", c);
printf_s("Integer: = %d\n", i);
printf_s("Real: = %f\n", fp);
return 0;
}
运行结果:
参考:
https://zh.cppreference.com/w/c/io/fscanf
https://www.standards.wiki/c/c_library_stdio_function_sscanf.html
https://www.standards.wiki/c/c_appendix_secure_function_sscanf_s.html
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/sscanf-sscanf-l-swscanf-swscanf-l?view=msvc-170
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/sscanf-s-sscanf-s-l-swscanf-s-swscanf-s-l?view=msvc-170