strncpy 的用法

在官方的文档中,http://www.cplusplus.com/refer…,例程的 strncpy 的用法是:

/* strncpy example */
#include <stdio.h>
#include <string.h>

int main ()
{
  char str1[]= "To be or not to be";
  char str2[40];
  char str3[40];

  /* copy to sized buffer (overflow safe): */
  strncpy ( str2, str1, sizeof(str2) );

  /* partial copy (only 5 chars): */
  strncpy ( str3, str2, 5 );
  str3[5] = '\0';   /* null character manually added */

  puts (str1);
  puts (str2);
  puts (str3);

  return 0;
}

注意到第 12 行,最后的参数是直接 sizeof,这样虽然可以防止溢出,但是其实还是 printf strlen 之类的不安全的,看看这个例子:

#include <stdio.h>
#include <string.h>

int main() {
    char str[3];
    memset(str, 0, sizeof(str));
    strncpy(str, "testtest", sizeof(str));
    printf("[%s][%d]\n", str, strlen(str));
    return 0;
}

看看输出:

$ ./a.out 
[tes][6]
$ ./a.out 
[tesx][6]
$ ./a.out 
[tesn][6]
$ ./a.out 
[tes][6]
$ ./a.out 
[tes€][6]
$ ./a.out 
[tes*][6]
$ ./a.out 
[tes¡][6]
$ ./a.out 
[tesP][6]
$ ./a.out 
[tes][6]

可以看到,最后那个 char 是不确定的,而且 strlen 也出错,那么,稳妥的做法应该是 -1

#include <stdio.h>
#include <string.h>

int main() {
    char str[3];
    memset(str, 0, sizeof(str));
    strncpy(str, "testtest", sizeof(str)-1);
    printf("[%s][%d]\n", str, strlen(str));
    return 0;
}
$ ./a.out 
[te][2]
$ ./a.out 
[te][2]
$ ./a.out 
[te][2]
$ ./a.out 
[te][2]

这样才能有稳定的输出

2 thoughts on “strncpy 的用法

Leave a Reply to ZRJ Cancel reply

Your email address will not be published. Required fields are marked *