Chinaunix首页 | 论坛 | 博客
  • 博客访问: 39396
  • 博文数量: 91
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 870
  • 用 户 组: 普通用户
  • 注册时间: 2016-08-23 11:14
  • 认证徽章:
文章分类

全部博文(91)

文章存档

2018年(21)

2017年(7)

2016年(63)

我的朋友

分类: 嵌入式

2018-10-15 00:05:35

strncpy()

1.常用用法

点击(此处)折叠或打开

  1. strncpy(buff, src, sizeof(buff));
  2. buff[sizeof[buff]-1] = '\0';

snprintf()

1.常用用法

点击(此处)折叠或打开

  1. snprintf(buff, sizeof(buff), "%s", src);
  另外,还有如:

点击(此处)折叠或打开

  1. snprintf(buff, sizeof(buff), src);
  或

点击(此处)折叠或打开

  1. sprintf(buff, src);
  也是可以的。

2.实战问题

关于使用sprintf时符号扩展的问题:

首先,符号扩展:即当短数据赋值给长数据时,将短数据的符号位填充到长数据的高字节位,以保证扩展后的数值大小不变。零扩展:即当短数据赋值给长数据时,用零来填充长数据类型的高字节位。

其次,我们直接看遇到的问题及分析过程:

点击(此处)折叠或打开

  1. #include <stdio.h>

  2. int main()
  3. {
  4.     char mac[6] = {0x01,0x8b,0x03,0x04,0x05,0x06};
  5.     char str[64] = {0};

  6.     sprintf(str, "%02x", mac[1]);

  7.     printf("%s\n", str);

  8.     return 0;
  9. }

输出结果是

0xffffff8b

把问题简单化后

点击(此处)折叠或打开

  1. #include <stdio.h>

  2. int main()
  3. {
  4.     char a = 0x8b;

  5.     printf("%#02x\n", a);

  6.     return 0;
  7. }

输出结果是

0xffffff8b

这里,我们先明确下width的功能


再试着这样做

点击(此处)折叠或打开

  1. #include <stdio.h>

  2. int main()
  3. {
  4.     char a = 0x8b;
  5.     int b = a;
  6.     unsigned int c = a;

  7.     printf("%#02x %#02x\n", b, c);

  8.     return 0;
  9. }

输出结果是

0xffffff8b 0xffffff8b
这里,我们用gcc -S sprintf3.c后,vim sprintf3.s来查看汇编代码

点击(此处)折叠或打开

  1. .file    "sprintf3.c"
  2.     .section    .rodata
  3. .LC0:
  4.     .string    "%#02x %#02x\n"
  5.     .text
  6. .globl main
  7.     .type    main, @function
  8. main:
  9.     pushl    %ebp
  10.     movl    %esp, %ebp
  11.     andl    $-16, %esp
  12.     subl    $32, %esp
  13.     movb    $-117, 31(%esp)
  14.     movsbl    31(%esp),%eax
  15.     movl    %eax, 24(%esp)
  16.     movsbl    31(%esp),%eax
  17.     movl    %eax, 20(%esp)
  18.     movl    $.LC0, %eax
  19.     movl    20(%esp), %edx
  20.     movl    %edx, 8(%esp)
  21.     movl    24(%esp), %edx
  22.     movl    %edx, 4(%esp)
  23.     movl    %eax, (%esp)
  24.     call    printf
  25.     movl    $0, %eax
  26.     leave
  27.     ret
  28.     .size    main, .-main
  29.     .ident    "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
  30.     .section    .note.GNU-stack,"",@progbits

显然,与这里的movsbl有关系,我们来看看什么是movsbl?(图片来自从汇编角度浅析C程序


那么,sprintf3.c应该这样写,才是我本来的意图

点击(此处)折叠或打开

  1. #include <stdio.h>

  2. int main()
  3. {
  4.     char a = 0x8b;
  5.     int b = (unsigned char)a;
  6.     unsigned int c = (unsigned char)a;

  7.     printf("%#02x %#02x\n", b, c);

  8.     return 0;
  9. }

输出结果才是我想要的

0x8b 0x8b

而开头的mac程序,也应该是这样写

点击(此处)折叠或打开

  1. #include <stdio.h>

  2. int main()
  3. {
  4.     char mac[6] = {0x01,0x8b,0x03,0x04,0x05,0x06};
  5.     char str[64] = {0};

  6.     sprintf(str, "%02x", (unsigned char)mac[1]);

  7.     printf("%s\n", str);

  8.     return 0;
  9. }

输出结果才是我想要的

0x8b

其实,该问题早在sprintf的百度百科中早已说明了


阅读(420) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
评论热议
请登录后评论。

登录 注册