在字符串处理过程当中会经常使用到如下几个函数 strcpy() sprintf() strcat() 但它们都存在必定的安全隐患,相对应用的安全版本为: strncpy() snprintf() strncat() int sprintf( char *buffer, const char *format, [ argument] … ) ; int snprintf(char *str, size_t size, const char *format, ...); 此两函数功能:把格式化的数据写入某个字符串. 返回值:字符串长度( strlen ) 首先让咱们来看下 sprintf()函数 Example /* sprintf example */ #include <stdio.h> int main (int argc, char *argv[]) { char buffer [50]; int n, a=5, b=3; n=sprintf (buffer, "%d plus %d is %d", a, b, a+b); printf ("[%s] is a %d char long string\n",buffer,n); return 0; } Example Output: [5 plus 3 is 8] is a 13 char long string 关于 sprintf() 不安全问题,主要由其参数决定, (1) 缓冲区溢出,char *buffer多大多小难以预测. (2) printf习惯形成的忘记第一个参数 (3) 参数对应问题,相对容易检查 snprintf(); 函数说明:最多从源串中拷贝n-1个字符到目标串中,而后再在后面加一个0。因此若是目标串的大小为n的话,是不会溢出。 函数返回值:若成功则返回欲写入的字符串长度,若出错则返回负值。 #include <stdio.h> int main() { char str[10]={0,}; snprintf(str, sizeof(str), "0123456789012345678"); //若是使用sprintf()将会出错 printf("str=%s\n", str); //snprintf(str, 18, "0123456789012345678"); //也能成功,可是不推荐使用 printf("str=%s\n", str); return 0; } Example Output: str=123456789 str=12345678901234567 提到sprintf()不得不说到在格式化时间的时候还有 sprintf 的孪生兄弟 strftime. size_t strftime ( char * ptr, size_t maxsize, const char * format, const struct tm * timeptr ); Example: /* strftime example */ #include <stdio.h> #include <time.h> int main (int argc, char *argv[]) { time_t rawtime; struct tm * timeinfo; char buffer [80]; time (&rawtime); timeinfo = localtime ( &rawtime ); strftime(buffer,80,"Now it's %Y%m%d%H%M%S",timeinfo); puts(buffer); return 0; } Example output: Now it's 20120701170808 extern char *strcat(char *dest,char *src); 函数说明:把src所指字符串添加到dest结尾处(覆盖dest结尾处的'\0')并添加'\0'. src和dest所指内存区域不能够重叠且dest必须有足够的空间来容纳src的字符串. 函数返回值:返回指向dest的指针。 extern char *strncat(char *dest,char *src,size_t n); 函数说明:把src所指字符串前n个字符添加添加到dest结尾处(覆盖dest结尾处的'\0')并添加'\0'. src和dest所指内存区域不能够重叠且dest必须有足够的空间来容纳src的字符串. 函数返回值:返回指向dest的指针。 char* strncat(char *dest,char *src,size_t n) { size_t dest_len = strlen(dest); size_t i; for (i = 0; i < n && src[i] != '\0' ; i++ ) { dest[dest_len + i] = src[i]; } dest[dest_len + i] = '\0'; return dest; } char *strcat(char *strDest, const char *strSrc) { char *address = strDest; assert((strDest != NULL) && (strSrc != NULL)); while(*strDest) { strDest++; } while(*strDest++ = *strSrc++) { NULL; } return address; } char *strcpy(char *dest, char *src); char *strncpy(char *dest, char *src, size_t n); strcpy只用来拷贝字符串,它遇到'\0'就结束拷贝。 strncpy将字符串src中最多n个字符复制到字符数组dest中,与strcpy不一样只有遇到NULL才中止复制 而是多了一个条件中止,就是说若是复制到第n个字符还未遇到NULL,也中止,返回指向dest的指针 可是如n>strlen(dest)的长度,dest栈空间溢出产生崩溃异常 char *strcpy(char *dest, const char *src) { char *p = dest; while (*src) *dest++ = *src++; *dest = '/0'; return p; } strncpy 标准用法 strncpy(path,src,sizeof(path)-1); path[sizeof(path)-1] = '\0'; len = strlen(path);