user-0 提问: C语言请问你们会用函数的安全版本吗，比如scanf_s，strncmp,fopen_s之类的？

回复:
user: user-1
content: 引用 17 楼 pcboyxhy 的回复:[quote=引用 13 楼 mLee79 的回复:] 进程线程， 网络， UI， FS 是操作系统的事， 关C啥事。  它们比C99更加不可移植[/quote]  比C99好多了， 做一个 POSIX 版本的， 一个 WIN32 版本的就解决了 90% 的问题， UI要么 GL/GLES 要么自己刷离屏表面， 跟系统相关的也就2,3个函数了， 反正我要么跑命令行，要么人肉贴 png， 省事，美工随便画画图也比我们做的界面好看多了。  遇到 RTOS 了， 定制下 代码也不会多。  而要用 C99 就基本得完全不甩 M$， 这也不太好，M$看起来也没有支持 C99 的计划， 我现在在 WIN32 下， 第三方库也全部用 mingw32 编译了， 比用 M$VC 去编译方便很多， 用用 C99 本来也没啥关系， 不过 C99 本来大部分特性也不是太有用， 有用的一般都有编译器扩展支持， 关系也不大。

user: user-2
content: 一般自己写代码不会用，编译也没有问题。 但是在公司如果遇到特殊情况，报错了就用呗，视情况而定，随波逐流。

user: user-3
content: 引用 13 楼 mLee79 的回复:进程线程， 网络， UI， FS 是操作系统的事， 关C啥事。  它们比C99更加不可移植

user: user-4
content: 引用 15 楼 mewiteor 的回复:如果想用请按照C11标准的规定使用。具体见C标准参考。 举个例子（不一定对）  #   ifdef __STDC_LIB_EXT1__     retByScanf = scanf_s("%[a-zA-Z0-9_]",str,size);     printf("scanf_s return %zu.\n",retByScanf); #   else     {         char format[64];         sprintf(format,"%%%zu[a-zA-Z0-9_]",size-1);         retByScanf = scanf(format,str);         printf("scanf return %zu.\n",retByScanf);     } #   endif  char s[4096]={0}; scanf("%4095[^\n]",s);  这是最省事的做法，看起来浪费，由于各种情况都可适用，反而更经济(可以安全替代gets())。 如果是数据库，则需要关心的是类型匹配，这部分必须手工做函数，标准库就是儿戏不能直接使用的。

user: user-1
content: 我一般来说， 库基本只用纯 C， 基本只用C89 特性， app/tools 啥的就随意了。 一般我写的库都在 win/linux/arm-linux/android/rtos ...  下都做测试。

user: user-3
content: 其实完全不用M$的东西也无妨，server和嵌入式有linux和freebsd，手机是ios和android绝对垄断，这些领域都没M$的事。传统PC端软件，倒也不需要C99，性能至关重要的用C++就是了，性能不敏感的现在用C#和Java的也无妨，不必跟C99较劲。

user: user-5
content: 如果想用请按照C11标准的规定使用。具体见C标准参考。 举个例子（不一定对）  // 先输入字符数组的容量，再输入一个字符串（只能包含字母、数字和下划线） #define __STDC_WANT_LIB_EXT1__ 1 #include <stdio.h> #include <malloc.h> #include <stdlib.h>  int main(void) {     size_t size,i,retByScanf;     char* str = NULL;      if (0==scanf("%zu",&size))     {         fputs("scanf return 0",stderr);         exit(EXIT_FAILURE);     }     while('\n'!=getchar());      str=(char*)calloc(size,sizeof(char));     if (NULL==str)     {         fputs("out of memory!",stderr);         exit(EXIT_FAILURE);     }  #   ifdef __STDC_LIB_EXT1__     retByScanf = scanf_s("%[a-zA-Z0-9_]",str,size);     printf("scanf_s return %zu.\n",retByScanf); #   else     {         char format[64];         sprintf(format,"%%%zu[a-zA-Z0-9_]",size-1);         retByScanf = scanf(format,str);         printf("scanf return %zu.\n",retByScanf);     } #   endif      if(retByScanf)         puts(str);     free(str);      return EXIT_SUCCESS; }

user: user-4
content: 关键是fgets,scanf本身就有很安全的用法，自己不用而去用有可能无法移植的“安全”代码，不觉得这实际上是另一种隐性BUG吗

user: user-1
content: 一个基本语言特性还在 C89 的竟然用20多年后的标准说事了， 古怪。  可移植性和对程序员的信任是 C 的灵魂, 这些函数没有啥存在的价值。

user: user-6
content: 引用 8 楼 mLee79 的回复:glibc 支持么， 不支持谁鸟啊。  C 标准应该是对语言的影响最小的委员会了， C99 都几乎没有人鸟， 就不说 C11 了。 支持不支持是一回事，但这不是方言。

user: user-1
content: glibc 支持么， 不支持谁鸟啊。  C 标准应该是对语言的影响最小的委员会了， C99 都几乎没有人鸟， 就不说 C11 了。

user: user-6
content: 引用 4 楼 mLee79 的回复:不用 _s 这类方言。 已经是C11标准

user: user-7
content: #pragma warning(disable:4996) ...

user: user-1
content: 进程线程， 网络， UI， FS 是操作系统的事， 关C啥事。

user: user-3
content: 引用 10 楼 mLee79 的回复:一个基本语言特性还在 C89 的竟然用20多年后的标准说事了， 古怪。  可移植性和对程序员的信任是 C 的灵魂, 这些函数没有啥存在的价值。  假设C89以外的东西不用， 进程线程的概念没有了，网络没有了，图形界面没有了，>2G的文件没的处理了，自个儿跟自个儿玩？

user: user-6
content: 引用 10 楼 mLee79 的回复:一个基本语言特性还在 C89 的竟然用20多年后的标准说事了， 古怪。  可移植性和对程序员的信任是 C 的灵魂, 这些函数没有啥存在的价值。 你不原意用就直说了嘛。 先扯不是标准，确定是标准后。就扯到glibc不支持，再接着又拿移植性说事。 只是一些函数而已，不牵涉到语言特性，爱用_s的函数就用，就算glibc不支持，找个实现贴到工程中也没不是什么难事。

user: user-8
content: 会的，我在用VS2013时就要用安全版本，不然会报错，又懒的调解

user: user-1
content: 不用 _s 这类方言。

user: user-9
content: 会

user: user-4
content: 没必要，在scanf("%s",s);时写成 scanf("%5s",s);//---假设s长度为6的话。 之所以出现函数使用的不安全完全是编程者自己偷懒图省事。