本篇介绍stdio.h头文件安全函数学习之vfprintf_s,vfscanf_s,vprintf_s,vscanf_s,vsnprintf_s,vsprintf_s,vsscanf_s。
vfprintf / vfprintf_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>
#include <stdarg.h>
#pragma warning(disable:4996)
void archives(const char* format, ...)
{
static int count = 0;
printf("No.%d Archives\n", ++count);
va_list args;
va_start(args, format);
vfprintf(stdout, format, args);
va_end(args);
putchar('\n');
}
void archives2(const char* format, ...)
{
static int count = 0;
printf("No.%d Archives2\n", ++count);
va_list args;
va_start(args, format);
vfprintf_s(stdout, format, args);
va_end(args);
putchar('\n');
}
int main(void)
{
archives("Name: %s\n", "Zhangshan");
archives("Name: %s\nGender: %c\n", "Lisi", 'M');
archives("Name: %s\nGender: %c\nAge: %d\n", "Wangwu", 'M', 25);
archives2("Name2: %s\n", "Zhangshan2");
archives2("Name2: %s\nGender2: %c\n", "Lisi", 'M');
archives2("Name2: %s\nGender2: %c\nAge: %d\n", "Wangwu", 'M', 25);
return 0;
}
运行结果:
参考:
https://zh.cppreference.com/w/c/io/vfprintf
https://www.standards.wiki/c/c_library_stdio_function_vfprintf.html
https://www.standards.wiki/c/c_appendix_secure_function_vfprintf_s.html
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/vfprintf-vfprintf-l-vfwprintf-vfwprintf-l?view=msvc-170
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/vfprintf-s-vfprintf-s-l-vfwprintf-s-vfwprintf-s-l?view=msvc-170
vfscanf / vfscanf_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>
#include <stdarg.h>
#pragma warning(disable:4996)
int getInteger(FILE* stream, const char* format, ...)
{
int count;
va_list args;
va_start(args, format);
count = vfscanf(stream, format, args);
va_end(args);
return count;
}
int call_vfscanf_s(FILE* istream, char* format, ...)
{
int result;
va_list arglist;
va_start(arglist, format);
result = vfscanf_s(istream, format, arglist);
va_end(arglist);
return result;
}
int main(void)
{
int integer[10];
int number;
FILE* pFile;
pFile = fopen("gchFile.txt", "r"); //gchFile.txt的内容为 101 0x101 -0101
number = getInteger(pFile, "%i%i%i", integer, (integer + 1), (integer + 2));
fclose(pFile);
for (int i = 0; i < number; ++i)
printf("integer[%d]: %d\n", i, integer[i]);
//vfscanf_s example
FILE* stream;
long l;
float fp;
char s[81];
char c;
if (fopen_s(&stream, "vfscanf_s.out", "w+") != 0)
{
printf("The file vfscanf_s.out was not opened\n");
}
else
{
fprintf(stream, "%s %ld %f%c", "a-string",
65000, 3.14159, 'x');
// Security caution!
// Beware loading data from a file without confirming its size,
// as it may lead to a buffer overrun situation.
// Set pointer to beginning of file:
fseek(stream, 0L, SEEK_SET);
// Read data back from file:
call_vfscanf_s(stream, "%s %ld %f%c", s, _countof(s), &l, &fp, &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/vfscanf
https://www.standards.wiki/c/c_library_stdio_function_vfscanf.html
https://www.standards.wiki/c/c_appendix_secure_function_vfscanf_s.html
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/vfscanf-vfwscanf?view=msvc-170
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/vfscanf-s-vfwscanf-s?view=msvc-170
vprintf / vprintf_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>
#include <stdarg.h>
#pragma warning(disable:4996)
void vprintf_text(const char* format, ...)
{
static int vpn = 0;
printf("No.%d vprintf_text\n", ++vpn);
va_list args;
va_start(args, format);
vprintf(format, args);
va_end(args);
putchar('\n');
}
void vprintf_s_text(const char* format, ...)
{
static int vpsn = 0;
printf_s("No.%d vprintf_s_text\n", ++vpsn);
va_list args;
va_start(args, format);
vprintf_s(format, args);
va_end(args);
putchar('\n');
}
int main(void)
{
vprintf_text("vprintf Name: %s\n", "Zhangshan");
vprintf_text("vprintf Name: %s\nGender: %c\n", "Lisi", 'M');
vprintf_text("vprintf Name: %s\nGender: %c\nAge: %d\n", "Wangwu", 'M', 25);
//vprintf_s example
vprintf_s_text("vprintf_s Name: %s\n", "Zhangshan");
vprintf_s_text("vprintf_s Name: %s\nGender: %c\n", "Lisi", 'M');
vprintf_s_text("vprintf_s Name: %s\nGender: %c\nAge: %d\n", "Wangwu", 'M', 25);
return 0;
}
运行结果:
参考:
https://zh.cppreference.com/w/c/io/vfprintf
https://www.standards.wiki/c/c_library_stdio_function_vprintf.html
https://www.standards.wiki/c/c_appendix_secure_function_vprintf_s.html
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/vprintf-vprintf-l-vwprintf-vwprintf-l?view=msvc-170
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/vprintf-s-vprintf-s-l-vwprintf-s-vwprintf-s-l?view=msvc-170
vscanf / vscanf_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>
#include <stdarg.h>
#pragma warning(disable:4996)
int vscanf_test(const char* format, ...)
{
int count;
va_list args;
va_start(args, format);
count = vscanf(format, args);
va_end(args);
return count;
}
int call_vscanf_s(char* format, ...)
{
int result;
va_list arglist;
va_start(arglist, format);
result = vscanf_s(format, arglist);
va_end(arglist);
return result;
}
int main(void)
{
int integer[10];
int number;
number = vscanf_test("%i%i%i", integer, (integer + 1), (integer + 2));
for (int i = 0; i < number; ++i)
printf("integer[%d]: %d\n", i, integer[i]);
//vscanf_s example
int i, result;
float fp;
char c, s[81];
wchar_t wc, ws[81];
result = call_vscanf_s("%d %f %c %C %s %S", &i, &fp, &c, 1,
&wc, 1, s, _countof(s), ws, _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/vfscanf
https://www.standards.wiki/c/c_library_stdio_function_vscanf.html
https://www.standards.wiki/c/c_appendix_secure_function_vscanf_s.html
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/vscanf-vwscanf?view=msvc-170
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/vscanf-s-vwscanf-s?view=msvc-170
vsnprintf / vsnprintf_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>
#include <stdarg.h>
#include <wtypes.h>
#pragma warning(disable:4996)
void vsnprintf_test(const char* format, ...)
{
static int vsnpf = 0;
char arr[100];
printf("No.%d Archives\n", ++vsnpf);
va_list args;
va_start(args, format);
vsnprintf(arr, sizeof(arr) / sizeof(arr[0]), format, args);
va_end(args);
puts(arr);
}
void vsnprintf_s_test(LPCSTR formatstring, ...)
{
int nSize = 0;
char buff[10];
memset(buff, 0, sizeof(buff));
va_list args;
va_start(args, formatstring);
nSize = vsnprintf_s(buff, _countof(buff), _TRUNCATE, formatstring, args);
printf("nSize: %d, buff: %s\n", nSize, buff);
va_end(args);
}
int main(void)
{
vsnprintf_test("vsnprintf Name: %s\n", "Zhangshan");
vsnprintf_test("vsnprintf Name: %s\nGender: %c\n", "Lisi", 'M');
vsnprintf_test("vsnprintf Name: %s\nGender: %c\nAge: %d\n", "Wangwu", 'M', 25);
//vsnprintf_s example
vsnprintf_s_test("%s %s", "Hi", "there");
vsnprintf_s_test("%s %s", "Hi", "there!");
vsnprintf_s_test("%s %s", "Hi", "there!!");
return 0;
}
运行结果:
参考:
https://zh.cppreference.com/w/c/io/vfprintf
https://www.standards.wiki/c/c_library_stdio_function_vsnprintf.html
https://www.standards.wiki/c/c_appendix_secure_function_vsnprintf_s.html
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/vsnprintf-vsnprintf-vsnprintf-l-vsnwprintf-vsnwprintf-l?view=msvc-170
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/vsnprintf-s-vsnprintf-s-vsnprintf-s-l-vsnwprintf-s-vsnwprintf-s-l?view=msvc-170
vsprintf / vsprintf_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>
#include <stdarg.h>
#include <wtypes.h>
#pragma warning(disable:4996)
void vsprintf_test(const char* format, ...)
{
static int vspf = 0;
char arr[100];
printf("No.%d Archives\n", ++vspf);
va_list args;
va_start(args, format);
vsprintf(arr, format, args);
va_end(args);
puts(arr);
}
void vsprintf_s_test(char const* const format, ...)
{
va_list args;
int len;
char* buffer;
va_start(args, format);
len = _vscprintf(format, args) // _vscprintf doesn't count
+ 1; // terminating '\0'
buffer = (char*)malloc(len * sizeof(char));
if (NULL != buffer)
{
vsprintf_s(buffer, len, format, args);
puts(buffer);
free(buffer);
}
va_end(args);
}
int main(void)
{
vsprintf_test("vsprintf Name: %s\n", "Zhangshan");
vsprintf_test("vsprintf Name: %s\nGender: %c\n", "Lisi", 'M');
vsprintf_test("vsprintf Name: %s\nGender: %c\nAge: %d\n", "Wangwu", 'M', 25);
//vsprintf_s example
vsprintf_s_test("%d %c %d", 123, '<', 456);
vsprintf_s_test("%s", "This is a string");
return 0;
}
运行结果:
参考:
https://zh.cppreference.com/w/c/io/vfprintf
https://www.standards.wiki/c/c_library_stdio_function_vsprintf.html
https://www.standards.wiki/c/c_appendix_secure_function_vsprintf_s.html
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/vsprintf-vsprintf-l-vswprintf-vswprintf-l-vswprintf-l?view=msvc-170
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/vsprintf-s-vsprintf-s-l-vswprintf-s-vswprintf-s-l?view=msvc-170
vsscanf / vsscanf_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>
#include <stdarg.h>
#include <wtypes.h>
#pragma warning(disable:4996)
int vsscanf_test(const char* s, const char* format, ...)
{
int count;
va_list args;
va_start(args, format);
count = vsscanf(s, format, args);
va_end(args);
return count;
}
int call_vsscanf_s(char* tokenstring, char* format, ...)
{
int result;
va_list arglist;
va_start(arglist, format);
result = vsscanf_s(tokenstring, format, arglist);
va_end(arglist);
return result;
}
int main(void)
{
int integer[10];
int number;
const char str[] = "101 0x101 -0101";
number = vsscanf_test(str, "%i%i%i", integer, (integer + 1), (integer + 2));
for (int i = 0; i < number; ++i)
printf("integer[%d]: %d\n", i, integer[i]);
//vsscanf_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:
call_vsscanf_s(tokenstring, "%80s", s, _countof(s));
call_vsscanf_s(tokenstring, "%c", &c, sizeof(char));
call_vsscanf_s(tokenstring, "%d", &i);
call_vsscanf_s(tokenstring, "%f", &fp);
// Output the data read
printf("String = %s\n", s);
printf("Character = %c\n", c);
printf("Integer: = %d\n", i);
printf("Real: = %f\n", fp);
return 0;
}
运行结果:
参考:
https://zh.cppreference.com/w/c/io/vfscanf
https://www.standards.wiki/c/c_library_stdio_function_vsscanf.html
https://www.standards.wiki/c/c_appendix_secure_function_vsscanf_s.html
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/vsscanf-vswscanf?view=msvc-170
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/vsscanf-s-vswscanf-s?view=msvc-170