ubuntu中使用snprintf的误区

来源:互联网 发布:市场营销实训软件 编辑:程序博客网 时间:2024/06/06 05:30
近期在开发android驱动时遇到一个有趣的现象:
1. 在android kernel中使用snprintf组包
char buf[256] = "abcd";
char test = 0xE1;  
snprintf(buf, sizeof(buf), "%s%02X", buf, test);
printk("buf = %s\n", buf);
结果:abcdE1
2. 同样在ubuntu中组包
结果:FFFFFFE1

这其实是两个问题下面做简要分析:
下面使用sprintf做简要分析,snprintf是一样的
1. sprintf 的原型为:
int sprintf(char *restrict s, const char *restrict format, ...);
其中 char* restrict s 的含义为通过s 指向的内存空间不得与其他指针参数指向的内存的空间重叠。比如如下的语句就是错误的用法, 因为参数1与参数3指向的内存重叠了。
但在android kernel中sprintf这种做法作为增强版的strcat,所以出现了android与ubuntu不一致现象。
sprintf(buf, "%s foo %d %d", buf, var1, var2);
在 ubuntu 8.10 所带的 gcc 中,如果编译时加入了优化选项(比如 -O1, -O2), 那么sprinf 会首先将 s 清空,比如如下的程序会输出 "fail", 而不是 "not fail"。
#include <stdio.h>
char buf[80] = "not ";
int main() {
  sprintf(buf, "%sfail", buf);
  puts(buf);
  return 0;
}
作为补救方案,可以使用如下的语句来代替:
sprintf(buf+strlen(buf), " foo %d %d", var1, var2);
2、而对于在ubuntu打印中出现FFFFFF的问题其实是因为E1超出了char类型的限制,为android kernel char类型可以正常打印128以上的char类型数据。
0 0
原创粉丝点击