stdio.h安全函数学习之gets_s,tmpnam_s,fopen_s,tmpfile_s,freopen_s

本篇介绍 stdio.h头文件中安全函数学习之gets_s,tmpnam_s,fopen_s,tmpfile_s,freopen_s。

实验环境 window11, VS2022

gets / gets_s  示例代码:

#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[20];  // 创建一个字符数组来存储输入的字符串
    //printf("please input one line text:\n");
    //char* ret = gets(str);  // VS2022 已经没有gets()函数了
    //printf("ret = %s\n", ret);
    //printf("The text you entered is:\n");
    //printf("str = %s\n", str);


    char str2[10];  // 创建一个字符数组来存储输入的字符串
    printf("please input one line text:\n");
    char* ret2 = gets_s(str2, sizeof str2);  // 调用gets_s()函数读取输入的字符串
    printf("ret2 = %s\n", ret2);
    printf("The text you entered is:\n");
    printf("str2 = %s\n", str2);

    printf("hello world\n");

    return 0;
}

运行结果:

参考:

https://zh.cppreference.com/w/c/io/gets
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/gets-s-getws-s?view=msvc-170

tmpnam / tmpnam_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)
{
    // 注意,编译器/连接器可能会发出安全警告,
    // C4996	'tmpnam': This function or variable may be unsafe.Consider using tmpnam_s instead.To disable deprecation, use _CRT_SECURE_NO_WARNINGS.See online help for details.safefunction	D : \vscpp\cpp20\cpp20standard\safefunction\stdio.c	21

    char* name1 = tmpnam(NULL);
    printf("temporary file name: %s\n", name1);

    char name2[L_tmpnam];
    if (tmpnam(name2))
        printf("temporary file name: %s\n", name2);
    char name3[L_tmpnam]; //L_tmpnam最长目录字符数
    int ret = tmpnam_s(name3, sizeof name3); //ret = 0表示正常,非0表示失败
    if (ret == 0)
    {
        printf("temporary file name3: %s\n", name3);
    }
    else
    {
        printf("temporery is error: %d\n", ret);
    }
    

    char name4[20];  
    int ret2 = tmpnam_s(name4, sizeof name4); //ret = 0表示正常,非0表示失败
    if (ret2 == 0)
    {
        printf("temporary file name4: %s\n", name4);
    }
    else
    {
        printf("temporery is error: %d\n", ret2);
    }

    return 0;
}

运行结果:

参考:

https://zh.cppreference.com/w/c/io/tmpnam
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/tmpnam-s-wtmpnam-s?view=msvc-170

fopen / fopen_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* fname = "./fopen_name.txt"; // 或 tmpnam(NULL);
    int is_ok = EXIT_FAILURE;

    FILE* fp = fopen(fname, "w+");
    if (!fp) {
        perror("File opening failed");
        return is_ok;
    }
    fputs("Hello, world!\n", fp);
    rewind(fp);//该函数将参数stream指向流的文件位置指示符设置为文件开头

    int c; // 注意:为处理 EOF 需要 int 而非 char
    while ((c = fgetc(fp)) != EOF) // 标准 C 的 I/O 文件读取循环
        putchar(c);

    if (ferror(fp))
        puts("I/O error when reading");
    else if (feof(fp)) {
        puts("End of file is reached successfully");
        is_ok = EXIT_SUCCESS;
    }

    fclose(fp);
    //remove(fname); //不移除


    const char* fname2 = "./fopen_name2.txt";  
    FILE* fp2;
    int ret = fopen_s(&fp2, fname2, "w+");  //ret == 0表示正常, 非0表示失败
    if (ret != 0) {
        perror("File opening failed2");
        return is_ok;
    }

    fputs("Hello, world-2!\n", fp2);
    rewind(fp2);

    int c2; // 注意:为处理 EOF 需要 int 而非 char
    while ((c2 = fgetc(fp2)) != EOF) // 标准 C 的 I/O 文件读取循环
        putchar(c2);

    if (ferror(fp2))
        puts("I/O error when reading-2");
    else if (feof(fp2)) {
        puts("End of file is reached successfully-2");
        is_ok = EXIT_SUCCESS;
    }

    fclose(fp2);
    //remove(fname2); //不移除

    return is_ok;
}

运行结果:

参考:

https://zh.cppreference.com/w/c/io/fopen
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/fopen-s-wfopen-s?view=msvc-170

tmpfile / tmpfile_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)
{
    printf("TMP_MAX = %d, FOPEN_MAX = %d\n", TMP_MAX, FOPEN_MAX);
    FILE* tmpf = tmpfile();
    fputs("Hello, world", tmpf);//将字符串写入到tmpf中
    rewind(tmpf);
    char buf[6];
    fgets(buf, sizeof buf, tmpf);//从给定文件流读取最多 count - 1 个字符并将它们存储于 str 所指向的字符数组。
    printf("got back from the file: '%s'\n", buf);

    //tmpfile_s
    FILE* stream;
    char tempstring[] = "String to be written";
    // Create temporary files.
    for (int i = 1; i <= 3; i++)
    {
        int ret = tmpfile_s(&stream); //ret == 0表示成功,非0表示失败
        if (ret)
            perror("ret = %d Could not open new temporary file\n", ret);
        else
            printf("ret = %d Temporary file %d was created\n", ret, i);
    }

    // Remove temporary files.
    printf("%d temporary files deleted\n", _rmtmp());
    return 0;
}

运行结果:

参考:

https://zh.cppreference.com/w/c/io/tmpfile
https://www.standards.wiki/c/c_library_stdio_function_tmpfile.html
https://www.standards.wiki/c/c_appendix_secure_function_tmpfile_s.html
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/tmpfile-s?view=msvc-170

freopen / freopen_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)
{
    //freopen example
    //puts("stdout is printed to console");
    //if (freopen("./redir.txt", "w", stdout) == NULL)
    //{
    //    perror("freopen() failed");
    //    return EXIT_FAILURE;
    //}
    //puts("stdout is redirected to a file"); // 写入 redir.txt
    //fclose(stdout);

    //freopen_s example
    FILE* stream;
    // Reassign "stderr" to "freopen.out":
    int ret = freopen_s(&stream, "./freopen.out", "w", stderr);

    if (ret != 0)
        fprintf(stdout, "error on freopen\n");
    else
    {
        fprintf(stdout, "successfully reassigned\n");
        fflush(stdout);
        fprintf(stream, "This will go to the file 'freopen.out'\n");
        fclose(stream);
    }
    system("type freopen.out");

    return EXIT_SUCCESS;
}

运行结果:

参考:

https://zh.cppreference.com/w/c/io/freopen
https://www.standards.wiki/c/c_library_stdio_function_freopen.html
https://www.standards.wiki/c/c_appendix_secure_function_freopen_s.html
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/freopen-s-wfreopen-s?view=msvc-170

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值